如果POST不在飞行前OPTIONS响应的Access Control Allow Methods值中,浏览器是否会阻止



我想我很理解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/

我的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

注意,服务器在对飞行前请求的响应中允许方法PUTDELETE,但不允许POST,这是实际CORS请求的方法。

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

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

TL;DR

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


更多详细信息

规格说明

和往常一样,答案在于Fetch标准(第4.8节(,该标准规定了CORS的工作方式:

  1. 方法是在给定Access-Control-Allow-Methods响应的头列表的情况下提取头列表值的结果

再往下看:

  1. 如果请求的方法不在方法中,请求的方法不是CORS安全列出的方法,并且请求的凭据模式为"include"方法不包含*,则返回网络错误

(我的重点(

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

CORS安全列表方法是一种GETHEADPOST方法。

解释

如果CORS请求的方法是GETHEADPOST中的一个,则浏览器不要求服务器在Access-Control-Allow-Methods报头中明确列出该方法,以使CORS预飞行成功。

实验

我发现Jake Archibald的CORS游乐场对测试我对CORS的(错误(理解很有用。在浏览器中运行这个特定的实例可能会让您相信,不需要显式地允许POST方法就可以使CORS预飞行成功。

最新更新