Etag标头不是从jQ​​uery.ajax()跨源XHR返回的

为什么以下最小例子中的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

    Etag header not returned from jQuery.ajax() cross-origin XHR   $(document).ready(function () { $.ajax('//localhost:8081/') .done(function (data, textStatus, jqXHR) { $('pre').text(jqXHR.getAllResponseHeaders()); }) .fail(function (jqXHR, textStatus, errorThrown) { $('pre').text(textStatus); }); });    

页面输出

 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报道)

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

从CORS规范 :

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

简单的响应标头仅限于:

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

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