4

我正在尝试发送跨域请求。就这Access-Control-Request-Headers一点而言,我在 FireFox、Chrome 和 Safari 中的行为有所不同。

Chrome :- Access-Control-Request-Headers:  origin, content-type, accept
Safari :- Access-Control-Request-Headers:  origin, content-type, accept
Firefox:- Access-Control-Request-Headers:  content-type

我的问题是:-

  1. 浏览器如何决定哪些标头将成为 Access-Control-Request-Headers 的一部分?
  2. 据我所知,Access-Control-Request-Headers 中应该只有自定义标头,但所有三个(accept、origin 和 content-type)都不是自定义标头。那么为什么它们是 Access-Control-Request-Headers 的一部分呢?
  3. 为什么行为因浏览器而异?
4

1 回答 1

10

这里发生了很多不同的事情,所以我一次回答一个。

Chrome 和 Safari 都基于 WebKit,这就是为什么您会在这些浏览器中看到相同的行为(Chrome 即将迁移到 Blink,但尚未掌握在用户手中)。

最新的 CORS 规范指出这Accept是一个简单的请求标头。Origin不包含在简单请求标头列表中,但是不支持它会很愚蠢,因为它是 CORS 的基础。所以从技术上讲,Firefox 正在做正确的事情。

但是请注意,尽管 Chrome/Safari 包含AcceptOrigin标头,但它们不会验证这些标头是否包含在Access-Control-Allow-Headers响应标头中。您可以通过访问以下链接来验证这一点:

http://client.cors-api.appspot.com/client#?client_method=PUT&client_credentials=false&client_headers=Accept%3A%20%2A%2F%2A&server_enable=true&server_status=200&server_credentials=false&server_methods=PUT&server_tabs=local

请注意,预检请求有 header Access-Control-Request-Headers: accept, origin,但Access-Control-Allow-Headers响应中没有。并且实际的 CORS 请求仍然成功。

Content-Type仅当其值为以下之一时,该标头才被视为简单请求标头:application/x-www-form-urlencodedmultipart/form-datatext/plain。所有其他值将触发预检。这可能就是您在这里看到的。

我不知道为什么浏览器会这样。这可能是值得在 WebKit 或 Firefox 留言板上询问的内容。下面是 WebKit 设置Access-Control-Request-Headers标头的代码:

https://trac.webkit.org/browser/trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp?order=name#L117

它似乎列出了所有标题,而没有删除简单的标题。我想响应端的代码只需要响应中的非简单标头Access-Control-Allow-Headers

于 2013-06-27T03:25:02.573 回答