jQuery.ajax() 跨域 XHR 未返回 Etag 标头 [英] Etag header not returned from jQuery.ajax() cross-origin XHR

查看:27
本文介绍了jQuery.ajax() 跨域 XHR 未返回 Etag 标头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么在以下最小示例中 jqXHR.getAllResponseHeaders() 没有返回 Etag 标头?

运行:node etag-server.js(然后访问http://localhost:8080/)

etag-server.js

var fs = require('fs'),http = 要求('http');var webServer = http.createServer(函数(请求,响应){response.writeHead(200, {"Content-Type": "text/html"});response.end(fs.readFileSync('frontend.html'));});var apiServer = http.createServer(函数(请求,响应){response.writeHead(200, {'Access-Control-Allow-Origin': 'http://localhost:8080','缓存控制':'无缓存','内容类型':'应用程序/json;字符集=utf-8','Etag':123,过期":-1,'Pragma': '无缓存'});response.end(JSON.stringify({ data: [1, 2, 3] }));});webServer.listen(8080);apiServer.listen(8081);

frontend.html

<!DOCTYPE html><html><头><title>jQuery.ajax() 跨域 XHR 未返回 Etag 标头</title><script src="//code.jquery.com/jquery-1.10.2.min.js" type="text/javascript"></script><脚本类型="文本/javascript">$(文档).ready(函数 () {$.ajax('//localhost:8081/').done(函数(数据,文本状态,jqXHR){$('pre').text(jqXHR.getAllResponseHeaders());}).fail(function (jqXHR, textStatus, errorThrown) { $('pre').text(textStatus); });});</脚本></头><身体><pre></pre></身体></html>

页面输出

缓存控制:无缓存内容类型:应用程序/json;字符集=utf-8过期:-1Pragma:无缓存

Etag 去哪儿了?它们被发送到浏览器:

HTTP/1.1 200 OK访问控制允许来源:http://localhost:8080缓存控制:无缓存内容类型:应用程序/json;字符集=utf-8电子标签:123过期:-1Pragma:无缓存日期:2014 年 1 月 25 日星期六 02:20:47 GMT连接:保持活动传输编码:分块

(由 Firebug 报告)

解决方案

客户端代码无法访问跨域响应中的 ETag 标头,除非服务器包含 Access-Control-Expose-Headers 响应中的标头,其值为ETag".任何非简单"响应标头都是如此.

来自 CORS 规范:

<块引用><块引用>

7.1.1 处理对跨域请求的响应用户代理必须过滤掉所有响应头,除了那些是简单响应头或字段名称是与 Access-Control-Expose-Headers 头(如果有)的值之一的 ASCII 大小写不敏感匹配的响应头,在将响应标头暴露给 CORS API 规范中定义的 API 之前.

简单的响应标头仅限于:

  1. 缓存控制
  2. 内容语言
  3. 内容类型
  4. 过期
  5. 最后修改时间
  6. 语用

客户端需要在响应中访问的所有其他标头必须通过我上面提到的响应标头暴露".

Why is the Etag header not being returned by jqXHR.getAllResponseHeaders() in the following minimal example?

Run with: node etag-server.js (then visit http://localhost:8080/)

etag-server.js

var fs = require('fs'),
    http = require('http');

var webServer = http.createServer(function (request, response) {
    response.writeHead(200, {"Content-Type": "text/html"});
    response.end(fs.readFileSync('frontend.html'));
});

var apiServer = http.createServer(function (request, response) {
    response.writeHead(200, {
        'Access-Control-Allow-Origin': 'http://localhost:8080',
        'Cache-Control': 'no-cache',
        'Content-Type': 'application/json; charset=utf-8',
        'Etag': 123,
        'Expires': -1,
        'Pragma': 'no-cache'
    });
    response.end(JSON.stringify({ data: [1, 2, 3] }));
});

webServer.listen(8080);
apiServer.listen(8081);

frontend.html

<!DOCTYPE html>
<html>
<head>
  <title>Etag header not returned from jQuery.ajax() cross-origin XHR</title>
  <script src="//code.jquery.com/jquery-1.10.2.min.js" type="text/javascript"></script>
  <script type="text/javascript">
    $(document).ready(function () {
        $.ajax('//localhost:8081/')
        .done(function (data, textStatus, jqXHR) {
            $('pre').text(jqXHR.getAllResponseHeaders());
        })
        .fail(function (jqXHR, textStatus, errorThrown) { $('pre').text(textStatus); });
    });
  </script>
</head>
<body>
<pre></pre>
</body>
</html>

Page Output

Cache-Control: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Pragma: no-cache

Where'd the Etag go? They're being sent to the browser:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://localhost:8080
Cache-Control: no-cache
Content-Type: application/json; charset=utf-8
Etag: 123
Expires: -1
Pragma: no-cache
Date: Sat, 25 Jan 2014 02:20:47 GMT
Connection: keep-alive
Transfer-Encoding: chunked

(as reported by Firebug)

解决方案

The ETag header present in cross-origin responses will not be accessible to client-side code unless the server includes an Access-Control-Expose-Headers header in its response, with a value of "ETag". This is true of any "non-simple" response headers.

From the CORS spec:

7.1.1 Handling a Response to a Cross-Origin Request User agents must filter out all response headers other than those that are a simple response header or of which the field name is an ASCII case-insensitive match for one of the values of the Access-Control-Expose-Headers headers (if any), before exposing response headers to APIs defined in CORS API specifications.

Simple response headers are limited to:

  1. Cache-Control
  2. Content-Language
  3. Content-Type
  4. Expires
  5. Last-Modified
  6. Pragma

All other headers that the client needs to access in the response must be "exposed" via the response header I mentioned above.

这篇关于jQuery.ajax() 跨域 XHR 未返回 Etag 标头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆