【问题标题】:Etag header not returned from jQuery.ajax() cross-origin XHRjQuery.ajax() 跨域 XHR 未返回 Etag 标头
【发布时间】:2014-02-16 05:20:59
【问题描述】:

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

运行:node etag-server.js(然后访问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>

页面输出

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

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

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

(由 Firebug 报告)

【问题讨论】:

    标签: jquery node.js xmlhttprequest cross-domain


    【解决方案1】:

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

    来自CORS spec

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

    简单的响应标头仅限于:

    1. 缓存控制
    2. 内容-语言
    3. 内容类型
    4. 过期
    5. 最后修改
    6. 编译指示

    客户端需要在响应中访问的所有其他标头必须通过我上面提到的响应标头“公开”。

    【讨论】:

    • 甜蜜!那很简单。这几天我要了解 CORS。
    • 不是为了我,是为了答案的完整性
    • @WalterTross 我已将我的评论替换为答案中的规范链接。
    猜你喜欢
    • 2012-03-22
    • 2017-03-22
    • 1970-01-01
    • 2016-08-03
    • 2011-07-03
    • 1970-01-01
    • 2012-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多