跨域和同源策略
虽然经常遇到和处理跨域的问题,但都是停留于用node的中间件,使用CORS的方式来允许跨域。
这篇文章主要理解跨域和同源策略,就不详细的描述解决方案了,因为跨窗口通信和iframe这些东西作为后端没怎么接触过。
跨域
跨域是指一个域下的文档或脚本试图去请求另一个域下的资源。
受浏览器的同源策略限制,无法跨域请求资源,这也是我们。
同源策略
所谓同源:
- 协议相同。
- 域名相同
- 端口相同
1 | http://www.example.com/dir2/other.html:同源 |
- Internet Explorer 的同源策略有两个主要的差异点:
- 授信范围(Trust Zones):两个相互之间高度互信的域名,如公司域名(corporate domains),则不受同源策略限制。
- 端口:IE 未将端口号纳入到同源策略的检查中,因此
https://company.com:81/index.html和https://company.com/index.html属于同源并且不受任何限制。
目的:
同源策略是一种浏览器安全策略,设想一个论坛网站可以获取到一个银行网站的cookie会有什么后果?
所以同源策略可以一定程度上防止xss(跨站脚本攻击)和csrf(跨域请求伪造)攻击。
限制范围:
文章开头我就说我平时处理的跨域问题主要是请求跨域,但是同源策略不止限制这种情况。
- Cookie、LocalStorage 和 IndexDB 无法读取。
- DOM 无法获得。
- AJAX 请求不能发送。
如何解决跨域问题
document.domain
适用范围:
cookie和iframe
假设有A网页w1.ruomu.com,B网页w2.ruomu.com,如果想要两个网页共享cookie
设置document.domain="ruomu.com",这样两个就可以共享cookie
window.postMessage
适用范围:
LocalStorage和iframe
window对象新增了一个window.postMessage方法,允许跨窗口通信,不论这两个窗口是否同源。
当然这个API也可以读取其它窗口的LocalStorage。
至于还有片段识别符和window.name等跨窗口通信的方案这里就先不说了
Ajax的跨域问题
作为后端,解决最多的就是这个。。
jsonp是一种非官方的跨域数据交互协议
基本思想:
通过添加一个<script>元素,向服务器请求JSON数据,因为浏览器具有src属性的标签,不受跨域限制(大部分吧),在请求参数传入回调函数方法名,后端返回该方法名的JSON数据。由于<script>元素请求的脚本,直接作为代码运行。这时,只要浏览器定义了该回调函数,该函数就会立即调用。
WebSocket
WebSocket协议很熟悉,使用ws://非加密和wss://加密 作为前缀。该协议不受同源策略影响。。
WebSocket请求头的信息包含了一个Origin,表示该请求的源。服务器可以根据这个字段,自行过滤。
CORS是跨源资源分享(Cross-Origin Resource Sharing)的缩写。它是W3C标准,是跨源AJAX请求的根本解决方法。相比JSONP只能发GET请求,CORS允许任何类型的请求。
- Access-Control-Allow-Origin : 必传字段, 表示接受请求的域名。
- Access-Control-Allow-Credentials:可选字段,表示是否允许发送
cookie。 - Access-Control-Expose-Headers: 可选字段,表示除了header的6个基本字段(
Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma),还需要什么字段。
ps: 后端一般都会有一个cors的中间件。。。
参考链接:
https://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html
http://www.ruanyifeng.com/blog/2016/04/cors.html
https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy