由于同源策略的限制,JavaScript 跨域的问题,一直是一个颇为棘手的问题。但是,HTML5 提供了在网页文档之间互相接收与发送信息的功能postMessage,IE8就开始支持了。使用这个功能,只要获取到网页所在窗口对象的实例,不仅同源(域 + 端口号)的 Web 网页之间可以互相通信,甚至可以实现跨域通信**。
1. 消息发送
otherWindow.postMessage(message, targetOrigin);
要想接收从其他窗口发送来的信息,必须对窗口对象的 onmessage 事件进行监听,其它窗口可以通过 postMessage 方法来传递数据。postMessage方法使用两个参数:第一个参数为所发送的消息文本,但也可以是任何 JavaScript 对象(通过 JSON 转换对象为文本),第二个参数为接收消息的对象窗口的 URL 地址,可以在 URL 地址字符串中使用通配符'*'指定全部地。
(1) otherWindow是对接收方窗口的引用,一般可以是以下几种方式:
(a)、window.frames[0].postMessage
(b)、document.getElementsByTagName('iframe')[0].contentWindow
(c)、window.opener.postMessage
(d)、event.source.postMessage
2. 消息接收
要对postMessage传来的消息进行处理,就要在其他页面或子页面上加一个onmessage事件(即 postmessage 引用的window进行消息接收)**
window.addEventListener('message',function(event){
console.log(event.data,event.origin,event.source);
});
这个onmessage事件接受一个参数,就是代码里的e,实际上他就是一个event对象。但他里面有很明显的3个参数与其他event对象不一样,即:
(a)data:顾名思义,是传递来的message
(b)source:发送消息的窗口对象
(c)origin:发送消息窗口的源url(协议+主机+端口号).比如从2.com往1.com发了消息,那么1.com收到消息时,e.origin就是2.com
最重要的就是data了,你可以用e.data取得他,然后做后续操作了。不过为了安全,你最好先判断一下e.source和e.origin是不是正确来源,再作操作。
注意:最好是通过addEventListener或attachEvent来加入onmessage事件,而不要直接window.onmessage=function(){},因为有的浏览器这样加会识别不了(如低版Firefox)