原理:

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 页面发送跨域信息,windowvar 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方式

  1. // 父页面 'http://localhost:8080'
  2. <div style="width:200px; float:left; margin-right:200px;border:solid 1px #333;">
  3. <div id="color">Frame Color</div>
  4. </div>
  5. <div>
  6. <iframe id="child" src="http://localhost:8087/index.html"></iframe>
  7. </div>
  8. <script type="text/javascript">
  9. window.onload=function(){
  10. window.frames[0].postMessage('getcolor','http://localhost:8000');
  11. }
  12. window.addEventListener('message',function(e){
  13. var color=e.data;
  14. document.getElementById('color').style.backgroundColor=color;
  15. },false);
  16. <script>
  1. // 子页面 'http://localhost:8000'
  2. <body style="height:100%;">
  3. <div id="container"
  4. onclick="changeColor();"
  5. style="widht:100%; height:100%; background-color:rgb(204, 102, 0);"
  6. >
  7. click to change color
  8. </div>
  9. <script type="text/javascript">
  10. var container=document.getElementById('container');
  11. window.addEventListener('message',function(e){
  12. if(e.source!=window.parent) return;
  13. var color=container.style.backgroundColor;
  14. window.parent.postMessage(color,'*');
  15. },false);
  16. function changeColor () {
  17. var color=container.style.backgroundColor;
  18. if(color=='rgb(204, 102, 0)'){
  19. color='rgb(204, 204, 0)';
  20. }else{
  21. color='rgb(204,102,0)';
  22. }
  23. container.style.backgroundColor=color;
  24. window.parent.postMessage(color,'*');
  25. }
  26. </script>
  27. </body>