跨域判定(跨域限制是浏览器行为,不是服务器行为)

跨域限制是浏览器行为,不是服务器行为。
  浏览器有个同源策略,对于不同源的站点之间的相互请求会做限制。如果非同源,共有三种行为受到限制:

  1. Cookie、LocalStorage 和 IndexDB 无法读取。
  2. DOM 无法获得。
  3. AJAX 请求不能发送。
      跨域限制仅仅是浏览器的行为,通过代理服务器,或者其他工具发送请求就能轻松绕过。
跨域时的动作
浏览器端

假设我们点击一个按钮去获取数据,获取数据的请求准备从浏览器发出,这时浏览器先会检测这条请求是同源还是跨域,也就是与按钮所在页面的地址是同源还是跨域,如果是同源,好说,直接发送出去;如果是跨域的请求,那就得hold住先,浏览器会在请求的http header中加上一个Origin字段,标明这个请求是从哪里发出来的,例如: Origin:http://neighbour.com:9000

服务器端

服务器收到请求会给与响应,响应的header里写明跨域的配置信息,告诉浏览器,它允许哪些域名发来的请求访问,哪些method可以执行。浏览器收到响应后自动判断能不能真正执行请求。

是否允许跨域的判定
跨域的判断流程

浏览器先根据同源策略对前端页面和后台交互地址做匹配,若同源,则直接发送数据请求;若不同源,则发送跨域请求。

服务器解析程序收到浏览器跨域请求后,根据自身配置返回对应文件头。若未配置过任何允许跨域,则文件头里不包含Access-Control-Allow-origin字段,若配置过域名,则返回Access-Control-Allow-origin+ 对应配置规则里的域名的方式

浏览器根据接受到的http文件头里的Access-Control-Allow-origin字段做匹配,若无该字段,说明不允许跨域;若有该字段,则对字段内容和当前域名做比对,如果同源,则说明可以跨域,浏览器发送该请求;若不同源,则说明该域名不可跨域,不发送请求。
(但是不能仅仅根据服务器返回的文件头里是否包含Access-Control-Allow-origin来判断其是否允许跨域,因为服务器端配置多域名跨域的时候,也会出现不能跨域的域名返回包里没有Access-Control-Allow-origin字段的情况。)
一个支持CORS的web服务器,有如下的判定字段,他们会在响应的header中写明

  • Access-Control-Allow-Origin:允许跨域的Origin列表
  • Access-Control-Allow-Methods:允许跨域的方法列表
  • Access-Control-Allow-Headers:允许跨域的Header列表
  • Access-Control-Expose-Headers:允许暴露给JavaScript代码的Header列表
  • Access-Control-Max-Age:最大的浏览器缓存时间,单位为s

其中Access-Control-Allow-Origin(访问控制之允许的源),在响应的http header中必须有的,表示允许访问本服务器的源头Origin(域名),可以是特定的域名列表,用逗号分隔,也可以是通配符 *,表示支持任意域名的访问。
除了限定源头Origin,还会限制请求的方法MethodHeader
如,如果服务器设定Access-Control-Allow-Methods:GET,那么跨域的POST请求无法在这个服务器执行。

流程

1.页面发送请求
2.浏览器根据同源策略做出判定,如果是同源请求,直接发送出去;如果是跨域请求,在HTTP HEADER加上Origin字段,或是先发送一次预检请求(preflight)。
3.服务器接收请求,根据自身跨域的配置(如允许哪些域名,什么样的Method访问),返回文件头。若未配置过任何允许跨域,则文件头里不包含Access-Control-Allow-origin字段,若配置过域名,则返回Access-Control-Allow-origin+ 对应配置规则里的域名的方式
浏览器接收到响应,根据响应头里的Access-Control-Allow-origin字段做匹配,如果没有这个字段,说明不匹配;如果有,将字段内容和当前域名做比对。如匹配,则可以发送请求。

跨域的请求形式

简单请求;非简单请求。

简单请求,方法仅限于 HEAD,GET或POST,且Header的字段不超过以下字段:HeadeAccept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencodedmultipart/form-datatext/plain (没有application/json, 说明如果发送JSON格式的body请求数据是一个非简单请求)

  非简单请求就是其他请求。简单请求浏览器会直接在请求的Header加上Origin字段再发送;非简单请求浏览器则会先发送一次预检请求,根据预检请求的结果,决定是否正式发送请求。

参考链接:https://segmentfault.com/a/1190000003710973#item-2-3
https://segmentfault.com/a/1190000012163420
https://juejin.im/post/5c1df8d4f265da615d72a1e4

发布了91 篇原创文章 · 获赞 82 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_42893625/article/details/105003755