浏览器的同源策略
为什么要有?
帮助阻隔恶意文档,减少可能被攻击的媒介。(就是为了安全)
如果非同源,共有三种行为受到限制
(1) Cookie、LocalStorage 和 IndexDB 无法读取。
(2) DOM 无法获得。
(3) AJAX 请求不能发送。
同源政策规定,AJAX请求只能发给同源的网址,否则就报错。
除了架设服务器代理(浏览器请求同源服务器,再由后者请求外部服务),有三种方法规避这个限制。
- JSONP
网页通过添加一个<script>
元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。 - WebSocket
WebSocket是一种通信协议,使用ws://(非加密)和wss://(加密)作为协议前缀。该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。
css
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
字段Origin
,表示该请求的请求源(origin),即发自哪个域名。服务器可以根据这个字段,判断是否许可本次通信.
- CORS 【待学习】
CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。
-- 简单请求
-- 非简单请求
凡是不同时满足上面两个条件,就属于非简单请求。
对于简单请求
浏览器自动在头信息之中,增加一个Origin字段。Origin说明本次请求来自哪个源(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这次请求。
- 如果不在许可范围内 :服务器会返回一个正常的HTTP回应。但浏览器会发现这个回应的头信息没有包含Access-Control-Allow-Origin字段,就知道出错了,从而抛出一个错误,被XMLHttpRequest的onerror回调函数捕获。注意,这种错误无法通过状态码识别 ,因为HTTP回应的状态码有可能是200。
(就是请求的资源会返回,但是浏览器发现不被许可,就要拦截,这也是一种错误,但不是网络请求的错误) - 在许可范围内:服务器返回的响应,会多出几个头信息字段。
css
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8
对于非简单请求
比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。
会在正式通信之前,增加一次HTTP查询请求 ,称为"预检"请求(preflight)。
- 浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中 ,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。
跨域资源共享 CORS 详解 https://www.ruanyifeng.com/blog/2016/04/cors.html
浏览器同源政策及其规避方法 https://ruanyifeng.com/blog/2016/04/same-origin-policy.html
跨域
url是由:协议、域名、端口 三部分组成,三个都相同的才能互相访问
请求的url任意一个部分和当前不同都叫产生了跨域请求,违反了浏览器同源策略,满足同源限制。但是请求的话浏览器是会放行的,也就是你请求的服务器会收到你的请求。
同源限制是指:服务器响应了你的请求,但是浏览器进行了拦截(也就是服务器其实是把你要的东西传回去了,但浏览器不给你)。
配置跨域
如果要避免同源策略进行跨域请求 ,我们可以通过代理服务器的方式进行请求
先请求同源服务器,然后在我们的服务器请求其他域,然后被请求的服务器返回给我们服务器内容(服务器之间不存在跨域),然后我们的服务器把响应结果给浏览器。
浏览器发现结果来自于同源,就不进行拦截了。
相当于进行了代请求并转发。
https://www.bilibili.com/video/BV1GN4y1M7P5?p=34\&vd_source=5cef5968d539682b683e7d01b00ad01b