虽然经常遇到和处理跨域的问题,但都是停留于用node的中间件,使用CORS的方式来允许跨域。

这篇文章主要理解跨域和同源策略,就不详细的描述解决方案了,因为跨窗口通信和iframe这些东西作为后端没怎么接触过。

跨域

跨域是指一个域下的文档或脚本试图去请求另一个域下的资源。

受浏览器的同源策略限制,无法跨域请求资源,这也是我们。

同源策略

所谓同源:
  • 协议相同。
  • 域名相同
  • 端口相同
1
2
3
4
http://www.example.com/dir2/other.html:同源
http://example.com/dir/other.html:不同源(域名不同)
http://v2.www.example.com/dir/other.html:不同源(域名不同)
http://www.example.com:81/dir/other.html:不同源(端口不同)
  • Internet Explorer 的同源策略有两个主要的差异点:
    • 授信范围(Trust Zones):两个相互之间高度互信的域名,如公司域名(corporate domains),则不受同源策略限制。
    • 端口:IE 未将端口号纳入到同源策略的检查中,因此 https://company.com:81/index.htmlhttps://company.com/index.html 属于同源并且不受任何限制。
目的:

同源策略是一种浏览器安全策略,设想一个论坛网站可以获取到一个银行网站的cookie会有什么后果?

所以同源策略可以一定程度上防止xss(跨站脚本攻击)和csrf(跨域请求伪造)攻击。

限制范围:

文章开头我就说我平时处理的跨域问题主要是请求跨域,但是同源策略不止限制这种情况。

  • Cookie、LocalStorage 和 IndexDB 无法读取。
  • DOM 无法获得。
  • AJAX 请求不能发送。

如何解决跨域问题

document.domain

适用范围

cookieiframe

假设有A网页w1.ruomu.com,B网页w2.ruomu.com,如果想要两个网页共享cookie

设置document.domain="ruomu.com",这样两个就可以共享cookie

window.postMessage

适用范围

LocalStorageiframe

window对象新增了一个window.postMessage方法,允许跨窗口通信,不论这两个窗口是否同源。

当然这个API也可以读取其它窗口的LocalStorage

至于还有片段识别符window.name等跨窗口通信的方案这里就先不说了

Ajax的跨域问题

​ 作为后端,解决最多的就是这个。。

JSONP

​ jsonp是一种非官方的跨域数据交互协议

基本思想:

​ 通过添加一个<script>元素,向服务器请求JSON数据,因为浏览器具有src属性的标签,不受跨域限制(大部分吧),在请求参数传入回调函数方法名,后端返回该方法名的JSON数据。由于<script>元素请求的脚本,直接作为代码运行。这时,只要浏览器定义了该回调函数,该函数就会立即调用。

WebSocket

​ WebSocket协议很熟悉,使用ws://非加密和wss://加密 作为前缀。该协议不受同源策略影响。。

​ WebSocket请求头的信息包含了一个Origin,表示该请求的。服务器可以根据这个字段,自行过滤。

CORS

​ 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-ControlContent-LanguageContent-TypeExpiresLast-ModifiedPragma),还需要什么字段。

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