Sec-Fetch-Mode 代替 Preflight
Posted
技术标签:
【中文标题】Sec-Fetch-Mode 代替 Preflight【英文标题】:Sec-Fetch-Mode instead of Preflight 【发布时间】:2019-12-22 09:35:55 【问题描述】:我创建了登录 FE 并完成了它。 和往常一样,我对 ajax 的 goto 是 Axios。我的代码如下。
const baseUrl = http://localhost:5000/project/us-central1/api
Axios.post(
`$baseUrl/v1/user/login`,
...data ,
headers:
Authorization: 'Basic auth...'
,
).then(r => console.log(r).catch(e =>console.log(e));
现在,当我尝试向本地 Firebase 云功能发送请求时。 我收到 400 错误请求。
检查请求后,我想知道为什么它没有发送任何预检请求,它应该这样做(据我所知),但我看到了一个名为 Sec-Fetch-Mode
的标头。我搜索了任何有点抽象的地方。而且我似乎无法弄清楚为什么我的请求仍然失败。
我的axios
配置中有什么遗漏吗?
我的 FE 在名为 live server(http://127.0.0.1:5500)
另外,我的firebase云功能已经启用cors
// cloud function expres app
cors(
origin: true
)
任何见解都会非常有帮助。
【问题讨论】:
可能是由您的标头引起的。为什么您使用自定义标头而不是“auth”参数? @EvgeniiMalikov,auth 参数是什么意思? @EvgeniiMalikov,对不起,我在 axios 上看到并测试过。它们是一样的,它只会吐出Authorization: Basic ..token
【参考方案1】:
OPTIONS
请求实际上正在发送,因为您正在发送一个带有 Authorization
标头的跨域请求,这被认为是不简单的。由于 Chrome 76 和 77 中的功能/错误,它不会显示在开发人员工具中。有关详细信息,请参阅 Chrome not showing OPTIONS requests in Network tab。
预检请求是一种允许在浏览器端拒绝跨域请求的机制,如果服务器不知道 CORS(例如:旧且未维护),或者如果它明确想要拒绝跨域请求(在这两种情况下,服务器都不会设置 Access-Control-Allow-Origin
标头)。 CORS 所做的可以通过检查Origin
标头在服务器端完成,但CORS 实际上在浏览器级别保护用户。它甚至在发送之前就阻止不允许的跨域请求,从而减少网络流量、服务器负载,并默认阻止旧服务器接收任何跨域请求。
另一方面,Sec-Fetch-Mode
是 Fetch metadata headers 之一(Sec-Fetch-Dest
、Sec-Fetch-Mode
、Sec-Fetch-Site
和 Sec-Fetch-User
)。这些标头旨在通知服务器有关发送请求的上下文。基于这些额外信息,服务器可以确定请求是否合法,或者直接拒绝。它们的存在是为了帮助 HTTP 服务器缓解某些类型的攻击,并且与 CORS 无关。
例如,旧的<img src="https://mybank.com/giveMoney?amount=9999999&to=evil@attacker.com">
攻击可以在服务器端检测到,因为Sec-Fetch-Dest
将设置为"image"
(这只是一个简单的示例,暗示服务器使用GET
方法公开端点使用不安全的 cookie 进行货币操作,这在现实生活中显然不是这样)。
总而言之,获取元数据标头并非旨在取代预检请求,而是与它们共存,因为它们满足不同的需求。而 400 错误很可能与这些无关,而与不符合端点规范的请求有关。
【讨论】:
恭喜你的回答真的很棒,我不知道这个,但我不认为它解决了海报的问题。 @Mr. Flibble 你能编辑原始帖子,让它专注于赏金吗?或者也许把赏金拿走?这只是 javascript 中的一个错字! @santamanno,这是一个错字。至于答案,这真的是一种传播。我真的不知道为什么会发生(400错误)。但是,当我添加时,responseType: json, and Cache-Control: no-cache, Content-Type: aplication/json
就可以了。
@Reyn 很高兴知道最后发生了什么!
使用 POST
不足以使 CORS 请求“简单”。问题中显示的自定义标头 Authorization
和 Content-Type: application/json
都将触发预检 OPTIONS 请求。开发人员工具中未显示预检请求的原因是 Chrome 76 和 77 中的功能/错误。有关详细信息,请参阅 ***.com/questions/57410051。【参考方案2】:
您的展开运算符上缺少一个点,这是正确的语法:
...数据
注意“数据”前面的三个点。
请在此处查看对对象使用扩展运算符:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
【讨论】:
以上是关于Sec-Fetch-Mode 代替 Preflight的主要内容,如果未能解决你的问题,请参考以下文章