执行预检请求时是否需要访问控制允许源 CORS 标头

Is the Access-Control-Allow-Origin CORS header required when doing a preflight request?

本文关键字:访问控制 许源 CORS 标头 请求 是否 执行      更新时间:2023-09-26

我们在网站上看到了众所周知的CORS错误:

XMLHttpRequest 无法加载 https://my-site.com/api。请求的资源上不存在"访问控制允许源"标头。因此,不允许访问源"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 标头。 然而,情况显然并非如此。

此处

和此处的所有示例都在实际响应中包含 Access-Control-Allow-Origin 标头,但不包括任何其他"必需">的 CORS 标头。 当我们将该标头添加到实际响应中时,错误就会消失。


所以我的问题是,两个请求中实际上都需要Access-Control-Allow-Origin标头吗? 这是在哪里说的? 为什么会这样呢?

是的,似乎两个响应都应该包含必要的 CORS 标头。

在简单跨源请求

和带印前检查的跨源请求中,"实际请求"遵循相同的行为,无论预检如何(分别为步骤 1 和步骤 3(,检查 CORS 标头。

  1. [...]应用发出请求步骤,并在发出请求时遵守以下请求规则

    • 。(截取:3xx 代码、中止和网络错误(

    • 否则

      执行资源共享检查。[...]

给定资源的资源共享检查算法如下:

  1. 如果响应包含零个或多个 Access-Control-Allow-Origin 标头值,则返回 fail 并终止此算法。

  2. [...]

预检请求仅阻止"实际请求"开始。