前端跨域通信解决方案总结

Posted by mieruko on 2016-12-25

什么是同源策略及限制

同源策略限制从一个源加载的文件或脚本如何与来自另一个源的资源进行交互
这是一个用于隔离潜在恶意文件的关键的安全机制

源 包括协议 域名和端口, 有一个不一样就是跨域

限制

  • Cookie, LocalStorage和indexDB无法读取
  • DOM无法获得
  • AJAX请求不能发送

跨域通信的几种方式

  • JSONP
  • WebSocket
  • Hash
  • CORS
  • postMessage

JSONP

JSON只能用于GET请求。
通过script标签的动态加载实现的。

网页通过添加一个script标签,向服务器请求JSON数据,这种做法不受同源政策限制;
服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。

WebSocket

WebSocket是H5的新的通信协议,使用ws://(非加密)和wss://(加密)作为协议前缀。该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。

Hash

在当前窗口打开一个iframe,我们可以通过给iframe的页面url设置hash的内容来实现数据的传递。

CORS

CORS就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。
服务器端对于CORS的支持,主要就是通过设置Access-Control-Allow-Origin来进行的。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。
CORS 的请求分两种,简单请求,非简单请求。
对于简单的跨域请求,浏览器会自动在请求的头信息加上Origin字段,表示本次请求来自哪个源(协议+域名+端口),服务端会获取到这个值,然后判断是否同意这次请求并返回。
非简单请求请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。
非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为”预检”请求(preflight)。一旦服务器通过了”预检”请求,以后每次浏览器正常的CORS请求,就都跟简单请求一样,会有一个Origin头信息字段。服务器的回应,也都会有一个Access-Control-Allow-Origin头信息字段。
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。

postMessage

允许跨窗口通信,不论这两个窗口是否同源。
postMessage方法的第一个参数是具体的信息内容,第二个参数是接收消息的窗口的源(origin),即”协议 + 域名 + 端口”。也可以设为*,表示不限制域名,向所有窗口发送。
接收方可以通过message事件,监听对方的消息。message事件的事件对象event,提供以下三个属性:

  • event.source:发送消息的窗口。
  • event.origin:消息发向的网址。
  • event.data:消息内容。