我有一个网站,React 前端驻留在(比方说)app.mydomain.com 上,api 位于 api.mydomain.com 上。
用户向 API 提交登录请求,登录成功后,会收到一个不错的 cookie 供以后使用。前端仅直接与 API 对话,因此 cookie 上的域只需设置为 api.mydomain.com。
我使用 Axios 执行将标志withCredentials
设置为 true 的请求,以接收 cookie。
服务器上允许 CORS 的标头如下:
Access-Control-Allow-Origin: http://app.mydomain.com
Access-Control-Allow-Methods: GET,POST,DELETE,PUT,OPTIONS
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true
Run Code Online (Sandbox Code Playgroud)
在这种情况下,Firefox 的响应如下:
但是,一旦将Access-Control-Allow-Headers
值设置得更具体,例如
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept
,一切都会正常。
Mozilla 表示,他们不允许对 Origin 值进行“通配”,而不是对 Headers 值进行“通配”,这一页同样如此,但没有提及任何内容。
为什么 Firefox 会有这样的行为?为什么我能找到的任何地方都没有提到它?
在包含 的预检响应中Access-Control-Allow-Credentials: true
,用作标头值的星号按Access-Control-Allow-Headers
字面解释,而不是解释为通配符(即“允许所有标头”)。
确实,有关 CORS 的 MDN 主页面并未明确说明此规则。然而,关于header 的更具体的MDN 页面Access-Control-Allow-Headers
明确地这样做了:
\n\n对于没有凭据的请求(没有 HTTP cookie 或 HTTP 身份验证信息的请求) ,值“
\n*
”仅算作特殊通配符值。在带有凭据的请求中,它被视为文字标头名称“*
”,没有特殊语义。请注意,Authorization
标头不能使用通配符,并且始终需要显式列出。
编辑(2023):正如sideshowbarker在评论中指出的那样,有关 CORS 的 MDN Web 文档页面已更新,现在声明如下:
\n\n\n响应凭证请求时:[...]
\n\n
\n- 服务器不得为响应标头值指定“
\n*
”通配符Access-Control-Allow-Headers
,而必须指定标头名称的显式列表;例如,Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
以下是来自更权威的Fetch 标准的澄清引用:
\n\n\n对于
\nAccess-Control-Expose-Headers
、Access-Control-Allow-Methods
和Access-Control-Allow-Headers
响应标头,该值*
被视为没有凭据的请求的通配符。\n
Access-Control-Expose-Headers
、Access-Control-Allow-Methods
和Access-Control-Allow-Headers
响应标头只能在 request\xe2\x80\x99s 凭据模式不是 " "*
时用作值。include
(我的重点)
\n规范规定的浏览器的相关规范要求位于https://fetch.spec.whatwg.org/#main-fetch的主获取算法中,在步骤 13 的子步骤 2 中:
\n\n\n如果请求的凭据模式不是\n"
\ninclude
" 并且headerNames包含*
,则将响应\xe2\x80\x99s CORS 公开的标头名称列表设置为响应\xe2\x80\x99s标头列表中的所有唯一标头 名称。
换句话说,spec 语句要求的浏览器行为*
是:
include
”,则浏览器需要检查响应中实际的响应头列表,并允许所有这些include
”,则要求浏览器仅允许任何字面名称为“ *
”的响应标头在那一步结束时,\xe2\x80\x99s 实际上有一条注释,内容几乎相同:
\n\n\n此时headerName之一仍可以存在
\n*
,但只会匹配名称为 的标头*
。
归档时间: |
|
查看次数: |
2412 次 |
最近记录: |