原理:
PageA 通过
window.postMessage()发送一个信息给 PageB,PageB 在window上添加一个事件监听绑定message事件可以接收到来自任何不同域名通过postMessage方法发送过来的信息,当 PageB 接收到 PageA 发送过来的信息时执行监听事件就 OK,在监听事件的event参数中包含了所有message事件接收到的相关数据。包括发送信息的内容event.data,发送信息的域名event.origin等等。 同样的,在 PageA 内添加一个事件监听绑定message事件,在 PageB 内通过postMessage方法发送信息给 PageA 一样可以进行跨域通信
window.postMessage() 中的 window 到底是什么呢?
PageA 页面内嵌入 iframe PageB 页面
- PageA 页面向 PageB 页面发送跨域信息,
window为 PageB 页面的window,即iframe.contentWindow。 - PageB 页面向 PageA 页面发送跨域信息,
window为 PageA 页面的window,即top或者parent。
PageA 页面内代码使用 window.open() 打开 PageB 页面
- PageA 页面向 PageB 页面发送跨域信息,
window为var pageB = window.open('http://192.168.197.157:3000/pageB.html')中的变量 pageB。 - PageB 页面无法主动给 PageA 页面发送跨域信息,必须先接收到 PageA 页面发送过来的
message然后再通过event.source发送给 PageA,没错… 此时的window就是event.source,即 PageA 的window
注意:
在
var targetPage = window.open('http://target.com')打开新页面之后需要等到[http://target.com](http://target.com)页面加载完成之后才能进行postMessage跨域通信,但是在跨域的情况下我们是无法对targetPage进行onload事件监听的,所以这里只能做 延迟setTimeout或者 定时setInterval处理。 同样的,在页面内嵌入iframe页面的情况下,我们也需要等到页面内的iframe加载完成之后进行postMessage跨域通信
代码:
iframe方式
// 父页面 'http://localhost:8080'<div style="width:200px; float:left; margin-right:200px;border:solid 1px #333;"><div id="color">Frame Color</div></div><div><iframe id="child" src="http://localhost:8087/index.html"></iframe></div><script type="text/javascript">window.onload=function(){window.frames[0].postMessage('getcolor','http://localhost:8000');}window.addEventListener('message',function(e){var color=e.data;document.getElementById('color').style.backgroundColor=color;},false);<script>
// 子页面 'http://localhost:8000'<body style="height:100%;"><div id="container"onclick="changeColor();"style="widht:100%; height:100%; background-color:rgb(204, 102, 0);">click to change color</div><script type="text/javascript">var container=document.getElementById('container');window.addEventListener('message',function(e){if(e.source!=window.parent) return;var color=container.style.backgroundColor;window.parent.postMessage(color,'*');},false);function changeColor () {var color=container.style.backgroundColor;if(color=='rgb(204, 102, 0)'){color='rgb(204, 204, 0)';}else{color='rgb(204,102,0)';}container.style.backgroundColor=color;window.parent.postMessage(color,'*');}</script></body>
