执行预检请求时是不是需要 Access-Control-Allow-Origin CORS 标头?
Posted
技术标签:
【中文标题】执行预检请求时是不是需要 Access-Control-Allow-Origin CORS 标头?【英文标题】:Is the Access-Control-Allow-Origin CORS header required when doing a preflight request?执行预检请求时是否需要 Access-Control-Allow-Origin CORS 标头? 【发布时间】:2015-02-06 15:05:59 【问题描述】:我们在我们的网站上看到了众所周知的 CORS 错误:
XMLHttpRequest 无法加载 https://my-site.com/api。请求的资源上不存在“Access-Control-Allow-Origin”标头。 Origin 'https://my-other-site.com' 因此不允许访问。
问题是,Access-Control-Allow-Origin
在预检请求中设置正确...
OPTIONS https://my-site.com/api HTTP/1.1
Host: my-site.com
Access-Control-Request-Method: POST
Origin: https://my-other-site.com
Access-Control-Request-Headers: my-custom-header, accept, content-type
Accept: */*
Referer: https://my-other-site.com/
...other stuff...
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://my-other-site.com
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: my-custom-header, accept, content-type
Access-Control-Expose-Headers: my-custom-header
...other stuff...
...但是,它没有在后续请求中设置。
POST https://my-site.com/api HTTP/1.1
Host: my-site.com
Accept: */*
My-Custom-Header: abcd123
Origin: https://my-other-site.com
Referer: https://my-other-site.com/
...other stuff...
HTTP/1.1 200 OK
My-Custom-Header: abcd123
...other stuff...
我不明白这个问题。根据我在网上阅读的一切,如果我们使用预检请求,我们不需要为实际请求添加 CORS 标头。但是,显然情况并非如此。
所有示例here 和here 在实际响应中都包含Access-Control-Allow-Origin
标头,但不包含任何其他“必需” CORS 标头。当我们将那个标头添加到我们的实际响应中时,错误就消失了。
所以我的问题是,两个请求中实际上都需要 Access-Control-Allow-Origin
标头吗?这是在哪里说明的?为什么这是真的?
【问题讨论】:
【参考方案1】:是的,看起来两个响应都应该包含必要的 CORS 标头。
在Simple Cross-Origin Request 和Cross-Origin Request with Preflight 中,“实际请求”遵循相同的行为,无论预检如何(分别为第 1 步和第 3 步)都检查 CORS 标头。
[...] 应用make a request steps 并在发出请求时遵守以下请求规则。
...(截断:3xx 代码、中止和网络错误)
否则
执行resource sharing check。 [...]
给定资源的资源共享检查算法如下:
如果响应包含零个或多个
Access-Control-Allow-Origin
标头值,则返回失败并终止此算法。[...]
预检请求只会阻止“实际请求”的开始。
【讨论】:
““实际请求”遵循相同的行为,无论预检如何都检查 CORS 标头” - 但这似乎不是真的。实际请求在没有Access-Control-Allow-Methods
或 Access-Control-Allow-Headers
标头的情况下正常工作。然而(正如我现在刚刚发现的),似乎Access-Control-Expose-Headers
标头在预检和实际请求中都是也 所必需的。 WTF!?以上是关于执行预检请求时是不是需要 Access-Control-Allow-Origin CORS 标头?的主要内容,如果未能解决你的问题,请参考以下文章