如果 POST 不在预检 OPTIONS 响应的 Access-Control-Allow-Methods 值中,浏览器是否会阻止 POST 请求?

Joe*_*kov 6 post cors preflight

我想我对 CORS 非常了解,但是当涉及到预检请求时,我仍然对浏览器的行为感到有点困惑。

假设浏览器发出此预检请求:

OPTIONS http://myserver.local:7000/api/order/4 HTTP/1.1
Host: myserver.local:7000
Connection: keep-alive
Accept: */*
Access-Control-Request-Method: POST
Access-Control-Request-Headers: x-my-custom-header
Origin: http://localhost:5000
Sec-Fetch-Mode: cors
Referer: http://localhost:5000/
Run Code Online (Sandbox Code Playgroud)

我的 API 返回:

HTTP/1.1 204 No Content
Date: Wed, 09 Mar 2022 12:52:50 GMT
Server: Kestrel
Access-Control-Allow-Headers: x-my-custom-header
Access-Control-Allow-Methods: PUT,DELETE
Access-Control-Allow-Origin: http://localhost:5000
Vary: Origin
Run Code Online (Sandbox Code Playgroud)

请注意,服务器允许在预检请求的响应中使用PUT和方法,但不允许,这是实际 CORS 请求的方法。DELETEPOST

由于实际请求的方法与标头中列出的方法不匹配,浏览器是否应该阻止此请求Access-Control-Allow-Methods?或者服务器用20x状态代码响应浏览器接受预检然后发送实际请求就足够了吗?

我的假设是,如果请求的方法不匹配,浏览器会比较允许方法并阻止请求......我错过了什么吗?

jub*_*0bs 7

长话短说

\n

不,浏览器不需要服务器显式允许该POST方法,因为后者作为所谓的CORS 安全列表方法,可以获得免费通行证。

\n
\n

更多细节

\n

规格说明了什么

\n

与往常一样,答案在于 Fetch 标准(第 4.8 节),它指定了 CORS 的工作原理:

\n
\n
    \n
  1. 方法Access-Control-Allow-Methods为提取给定标头列表值和响应\xe2\x80\x99s 标头列表的结果。
  2. \n
\n
\n

再往下:

\n
\n
    \n
  1. 如果 request\xe2\x80\x99s 方法不在methods中,request \xe2\x80\x99s 方法不是 CORS 安全列表方法,并且 request\xe2\x80\x99s 凭据模式是ormethods"include"不包含,则返回网络错误。*
  2. \n
\n
\n

(我的重点)

\n

什么是CORS 安全列表方法?该术语的定义见第 2.2.1 节

\n
\n

CORS 安全列表方法是GETHEAD或 的方法POST

\n
\n

解释

\n

如果 CORS 请求的方法是GETHEAD或之一POST,则浏览器不要求服务器在标头中显式列出该方法Access-Control-Allow-Methods以使 CORS 预检成功。

\n

实验

\n

我发现Jake ArchibaldCORS 游乐场对于测试我对 CORS 的(错误)理解很有用。在浏览器中运行此特定实例POST可能会让您相信,无需显式允许该方法即可使 CORS 预检成功。

\n