我希望更好地理解这个问题。我目前所使用的思维模型如下:
1. JS 托管在 foo.com 上,希望访问托管在 bar.com 上的资源。这不是浏览器想要向其用户公开的事情,除非可以证明 bar.com 欢迎此请求。
2. 因此,foo.com JS 实际上将请求分成两半。首先,我们通过 XMLHttpRequest 对象发送一个不带数据的请求(GET、POST 等)。bar.com 服务器返回它通常对任何请求响应的内容,其中可能包括 Access-Control-Allow-Origin 标头。(编辑:这是一个误解——请参见下面 apsillers 的优秀评论)
3. 如果浏览器确实收到了这样的标头,则会扫描其中的 Origin(在本例中为 foo.com)。如果存在,则继续发送它被要求发送的实际请求。否则,它会拒绝。(编辑:这也不完全正确)
如果这个模型是正确的,那么我不明白为什么浏览器会在这个初步请求中发送 Origin 标头。难道检查匹配不是在客户端进行吗?发送这个标头有什么作用?
1. JS 托管在 foo.com 上,希望访问托管在 bar.com 上的资源。这不是浏览器想要向其用户公开的事情,除非可以证明 bar.com 欢迎此请求。
2. 因此,foo.com JS 实际上将请求分成两半。首先,我们通过 XMLHttpRequest 对象发送一个不带数据的请求(GET、POST 等)。bar.com 服务器返回它通常对任何请求响应的内容,其中可能包括 Access-Control-Allow-Origin 标头。(编辑:这是一个误解——请参见下面 apsillers 的优秀评论)
3. 如果浏览器确实收到了这样的标头,则会扫描其中的 Origin(在本例中为 foo.com)。如果存在,则继续发送它被要求发送的实际请求。否则,它会拒绝。(编辑:这也不完全正确)
如果这个模型是正确的,那么我不明白为什么浏览器会在这个初步请求中发送 Origin 标头。难道检查匹配不是在客户端进行吗?发送这个标头有什么作用?
Origin
头可能在这里很有用,因为任何来源都可以成功地向任何其他来源发送GET/POST请求,但如果浏览器阻止它,则响应可能对JavaScript不可见。(除了GET和POST之外的请求在成功的OPTIONS预检之前不允许到达服务器,这一点您已经理解了。) - apsillers