CORS,全名为跨域资源共享,是为了让不同网站的页面之间互相访问数据的机制。简单来说,CORS 的工作机制是这样的:网站 A 请求网站 B 的资源,网站 A 发起的请求会在
Origin
请求头上带上自己的源(
origin
)信息,如果网站 B 返回的响应头里有
Access-Control-Allow-Origin
响应头,且响应头的值是网站 A 的源(或者是
*
),那么网站 A 就能成功访问到这份资源,否则就报跨域错误。
浏览器在一般的
<img>
标签下发起的就是个非 CORS 请求,而在
XHR/fetch
下默认发起的就是 CORS 请求;还比如在一般的
<script>
标签下发起的是非 CORS 请求(所以才能有 jsonp),而在新的
<script type="module"中
发起的是 CORS 请求。
当我们把
Access-Control-Allow-Origin
固定写死为
*或者固定的一个网站,不论请求头里的
Origin
是什么,甚至没有
Origin
也一样返回那个值,我们称这时的响应为无条件型CORS响应。
条件型CORS响应有两种情况:
1.有Origin请求头才返回
Access-Control-Allow-Origin
响应头,没有就不返回
2.设置*.taobao.com,当一级域名不同时就不返回
条件型CORS会遇到这样一种场景:在同一个浏览器下,先打开了
foo.taobao.com
上的一个页面,访问了我们的资源,这个资源被浏览器缓存了下来,和资源内容一起缓存的还有
Access-Control-Allow-Origin: https://foo.taobao.com
响应头。这时又打开
bar.taobao.com
上的一个页面,这个页面也要访问那个资源,这时它会读取本地缓存,读到的
Access-Control-Allow-Origin
头是缓存下的
https://foo.taobao.com
而不是自己想要的
https://bar.taobao.com
,这时就报跨域错误了,虽然它应该是能访问到这份资源的。
这时我们设置Vary: Origin 让同一个 URL 有多份缓存,这样通过不同的方式进行请求,origin不同就不会调用缓存,也就不会遇到跨域问题了。
愿所有远方终将抵达
愿爱你的人一直都在