为什么Access-Control-Request-Headers中包含非自定义标头?

时间:2013-06-26 20:56:10

标签: ajax google-chrome firefox http-headers cors

我正在尝试发送跨域请求。就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. 为什么浏览器的行为有所不同?

1 个答案:

答案 0 :(得分:9)

这里有很多不同的东西,所以我会一次一个地回答它们。

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

请注意,预检请求的标头为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响应中的非简单标题。