问题

在 Group API 里面使用 ETag 作为并行修改的控制,但是发现在 Chrome 和 Firefox 中,从 Ajax 的 XHR 里面拿不到 ETag,只能拿到 Content-Type

分析

Cross-Origin Resource Sharing 标准可知,默认的情况下,ETag 是会被屏蔽的,所以需要在 server 端设置 Access-Control-Expose-Headers headers

How Response Header is Filtered:

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.
Note: The getResponseHeader() method of XMLHttpRequest will therefore not expose any header not indicated above.

Simple Response Header:

A header is said to be a simple response header if the header field name is an ASCII case-insensitive match for one of the following:

  • Cache-Control
  • Content-Language
  • Content-Type
  • Expires
  • Last-Modified
  • Pragma

解决办法

在 server 端设置 Access-Control-Expose-Headers headers,像 GitHub 的一样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
HTTP/1.1 200 OK
Server: GitHub.com
Date: Tue, 21 Jun 2016 02:05:57 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 5
Status: 200 OK
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59
X-RateLimit-Reset: 1466478357
Cache-Control: public, max-age=60, s-maxage=60
Vary: Accept
ETag: "98f0c1b396a4e5d54f4d5fe561d54b44"
X-GitHub-Media-Type: github.v3
Access-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval
Access-Control-Allow-Origin: *
Content-Security-Policy: default-src 'none'
Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
X-Content-Type-Options: nosniff
X-Frame-Options: deny
X-XSS-Protection: 1; mode=block
Vary: Accept-Encoding
X-Served-By: 8a5c38021a5cd7cef7b8f49a296fee40
X-GitHub-Request-Id: B72926E3:551F:10CAF81:5768A104

[

]