这里发生了很多不同的事情,所以我会一次回答一个。
Chrome 和 Safari 都基于 WebKit,这就是为什么您会在这些浏览器中看到相同的行为(Chrome 很快就会转向 Blink,但尚未掌握在用户手中)。
最新的 CORS 规范指出Accept
是一个简单的请求头。Origin
不包含在简单请求标头列表中,但如果不支持它那就太愚蠢了,因为它是 CORS 的基础。所以从技术上来说,Firefox 正在做正确的事情。
但请注意,尽管 Chrome/Safari 包含Accept
and Origin
标头,他们不验证这些标头是否包含在Access-Control-Allow-Headers
响应头。您可以通过访问以下链接来验证这一点:
请注意,预检请求具有标头Access-Control-Request-Headers: accept, origin
,但是没有Access-Control-Allow-Headers
在回应中。并且实际的 CORS 请求仍然成功。
The Content-Type
仅当 header 的值为以下之一时,才将其视为简单请求标头:application/x-www-form-urlencoded
, multipart/form-data
, or text/plain
。所有其他值都将触发预检。这可能就是您在这里看到的。
我不知道为什么浏览器会这样。这可能值得在 WebKit 或 Firefox 留言板上询问。这是 WebKit 设置的代码Access-Control-Request-Headers
header:
https://trac.webkit.org/browser/trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp?order=name#L117 https://trac.webkit.org/browser/trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp?order=name#L117
它似乎列出了所有标题,但没有删除简单的标题。我想响应端有代码只需要非简单的标头Access-Control-Allow-Headers
回复。