持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第17天,点击查看活动详情
跨源资源共享(CORS)(或通俗地译为跨域资源共享)是一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其它 origin(域,协议和端口),使得浏览器允许这些 origin 访问加载自己的资源。跨源资源共享还通过一种机制来检查服务器是否会允许要发送的真实请求,该机制通过浏览器发起一个到服务器托管的跨源资源的"预检"请求。在预检中,浏览器发送的头中标示有HTTP方法和真实请求中会用到的头。
当你遇到浏览器跨域请求时候是不是有下面这样的原因:为什么简单请求直接就发送了,非简单请求还要先发一个 options 方法的预检请求?
-
你是不是觉得这是不是设计有问题?换你来设计的话是不是不分什么简单不简单请求,全都先发一个 options 。或者全都直接直接发原请求。而现在这样不上不下的设计真的很奇怪啊。
-
其实不然,原因如下:
-
在如今的情况下,有很多历史原因得不到解决,为了向前兼容,就会出现很多奇奇怪怪的地方,人总不能在十几年前就预判现在的发展吧,
-
其次,get请求单独发送会十分浪费性能,虽然有长连接,但是像post之类的请求直接发送,很容易泄露数据,这样一来跨域的限制不就废了。
-
要知道跨域是需要拿到响应头,才能知道允不允许跨域,其主要是防止你的网站盗用别人网站的凭据刷 api ,这样至少可以保证别人盗用你网站 cookie 的 POST 发都发不出去
-
还有浏览器加载 js 跟 html 、css 、jpg 这些静态文件默认都是 GET ,一个网站在打开的一瞬会大量加载这些文件。往往加载这些文件的时候不会携带 cookie 等机密数据,所以就不预先 option 了,完全没必要。但是 fetch 、xhr 、ajax 等发送请求往往是带 cookie 的,这时候又不好单独鉴别是不是 fetch 跟 xhr 、ajax 发的 GET 请求,所以就只给 POST 预检 option ,不管 GET 了
-
可能是因为简单请求的 http 报文小,发过去就算被拒绝了代价也比较小。非简单请求往往报文比较大,发过去再拒绝会造成资源浪费。而增加 options 预检,无论从时间还是空间维度,未增加过大负担,但带来的好处却显而易见。
一种简单的方式是可以走其他方式发,比如 get 用图片的 src ,post 构造个表单直接 submit ,为了向上兼容不能拦这些,单独拦截异步请求发送的跨域请求就没有意义了 复杂请求因为无法用这种手段构造,所以拦截跨域是有意义的,但是全拦了大家又不方便,所以改用 option 询问一下服务器该不该拦