出于浏览器的同源策略,我们经常会遇到浏览器跨域的问题。
简单的说跨域基本解决方案是:
-
GET请求用JSONP
-
其他请求用同源iframe做代理
JSONP的介绍很多,这里就不多说了。
而同源iframe做代理主要是主窗口与iframe的通讯问题,因为这里也有同源策略。常见的方法是使用window.name或者通过url param来通讯。但这些方法都需要反复加载iframe来完成的,资源消耗较高,有没有更好的方案呢?
window.postMessage
window.postMessage最早由IE8引入,主要为了解决跨文档通讯问题,以下使其支持列表:
Feature |
Chrome |
Firefox (Gecko) |
Internet Explorer |
Opera |
Safari (WebKit) |
Basic support |
1.0 |
6.0 (6.0) [1] [4] |
8.0 [2] [3] |
9.5 |
4.0 |
transfer argument |
? |
20.0 (20.0) |
Not supported |
? |
? |
otherWindow.postMessage(message, targetOrigin, [transfer]);
otherWindow:目标窗口,是 window.frames 属性的成员或者由 window.open 方法创建的窗口
-
message: 要发送的消息,类型为 String、Object (IE8、9 不支持)
-
targetOrigin: 限定消息接收范围,不限制请使用 ‘*’
message事件
再通过绑定该窗口的message事件,来获取信息,例如:
window.addEventListener('message', function (event) {
console.log(event.data);
}, false);
跨非同源文档通讯
这给我们提供了一种跨非同源文档通讯方案。这里有一个简单的例子:
http://html5demos.com/postmessage2
方案基本原理
基本原理现在就比较清晰了,我们依然使用同源iframe做代理,但是主页面与iframe的通讯方式是利用postMessage实现的。
现成方案
如果你已经只为IE8以上浏览器用户服务了(国外项目基本已经将IE6、7淘汰了),而且你不想处理这些兼容性问题,那么你可以选用下面老外实现的现成方案:
https://github.com/jpillora/xdomain
(完)
大家有什么问题或技术上的想法可以在此与大家分享,也可以加入前端爱好者QQ群(141999928)一起学习进步:
【幸凡前端技术交流群】
如果您觉得本文的内容对您的学习有所帮助,捐赠与共勉,支付宝(左)或微信(右)