二分之一

Just Jason's Blog

实现跨域通信(跨文档消息传输)的几种方法(crossMessageEvent.js)

最近两天为实现一个跨域通信的问题,对这个问题进行了相关的学习,心得一二,在此分享。

window.postMessage()方法

HTML5给我们带来了安全的跨域通信接口,即window.postMessage()方法。它方法原型是:

window.postMessage(msg, domain);

该方法的浏览器支持情况:E8+, FF3+, Chrome, Safari,且在IE下,msg参数必须是string,不能是object.由此可见,我们只要考虑IE6,IE7下的跨域实现。

一、方案一

使用window.postMessage + window.opener实现,该方式是利用IE6,7 opener hack的方式实现跨域,可以算一个安全漏洞。

实现方式:

www.a.com/a.html

var otherWindow = document.getElementById("ifr_a").contentWindow; //ifr_a为嵌套b.html的iframe ID
otherWindow.opener={
    postMessage:function(str){
        alert(str);
    }
}

www.b.com/b.html

parent.opener={
    postMessage:function(str){
        alert(str);
    }
}

发送消息:

window.opener.postMessage(message);

这样目标页面就能收到消息了。

我做了一下JS的封装,大家可以直接下载使用:crossMessageEvent_opener.js

下载:crossMessageEvent_opener.js

otherWindow:为目标窗口的window对象
message:消息内容,可以是object
targetOrigin:目标窗口的域 [可选]

CrossMessageEvent.receiveMessage(funciton(event){
alert(event.data); //event.data为message的内容
});

该方法的优点:

不需要使用代理页面,简单直接。

该方法的缺点:

只要打过微软的安全补丁.kb2497640就不能用了。

二、方案二

使用Iframe来实现跨域。

理论上使用Iframe的原则:

实现方式:

图例中表明了各个页面的iframe嵌套关系。

b.html向a.html发送消息:

a.html向b.html发送消息:

PS:我同事糖饼就是用这个方法实现的:http://www.planeart.cn/?p=1620

三、方案三:crossMessageEvent.js【推荐】

使用window.postMessage + hashtag轮询实现

实现方式:

通过改变目标窗口的location.hash值,目标页面进行轮询监听hash变化,来进行消息传递。

该种方式,不需要使用代理页面,可以避免iframe跨域带来的不稳定因素,由于需要一个定时器,效率稍低,但对于不是频繁的消息传递还是够用的。

crossMessageEvent.js就是采用这种方式来实现ie6,ie7的跨域消息传递。

crossMessageEvent.js使用:

crossMessageEvent.js下载:crossMessageEvent

CrossMessageEvent.postMessage(otherWindow, message, targetOrigin);

otherWindow:为目标窗口的window对象 message:消息内容,可以是object targetOrigin:目标窗口的域 [可选]

CrossMessageEvent.receiveMessage(funciton(event){
    alert(event.data); //event.data为message的内容
});

该方法的缺点是,会改变URL的hash,导致历史记录发生相应的变化,影响浏览器的前进和后退,且数据暴露在URL。

四、方案四

b页面给a页面发送消息采用方案二中的iframe代理方式。
a页面给b页面发送消息采用hash轮询的方式。
这样可以避免b页面将顶级页面的URL中的hash改变。

———————————————————

参考文献:

http://www.cnblogs.com/xueduanyang/archive/2011/08/23/2150090.html

http://www.alloyteam.com/2012/08/lightweight-solution-for-an-iframe-cross-domain-communication/

http://www.planeart.cn/?p=1620

最后修改时间:2014年9月9日星期二晚上7点41