跨域通信–Window.postMessage()

一、跨源通信概述

源:协议、端口号(https默认值433)、主机域名(document.domain)
作用:向目标窗口派发MessageEvent消息(四个属性)
兼容参考

MessageEvent四个属性:
1.message(类型)
2.data(window.postMessage的第一个参数)
3.origin(调用postMessage时页面的当前状态)
4.source(调用postMessage的窗口信息)

二、postMessage语法:

otherWindow.postMessage(message, targetOrigin, [transfer]);

otherWindow: 其他窗口(目标窗口)的一个引用,比如iframe的contentWindow属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames
(如父窗口向内嵌的iframe窗口发送信息)
message :信息内容,低版本浏览器只支持字符串,高版本可以各种数据都行
targetOrigin :目标窗口的源,可以是字符串*表示无限制,或URI,需要协议端口号和主机都匹配才会发送
transfer:参考MDN

三、接收postMessage发送的信息MessageEvent

window.addEventListener("message", function(MessageEvent){
  var origin = event.origin || event.originalEvent.origin; 
  ....
  }, false);

四、demo–利用iframe嵌套父子窗口通信

父窗口:

<!--我是父窗口-->  
<div class="parent" >
      <iframe src="子窗口链接" id="iframe"></iframe>
</div>
<script>
//监听子窗口信息
 window.addEventListener('message',function(event){
   ...
   })
//父窗口给子窗口发消息,
document.getElementByID('iframe').contentWindow.postMessage(msg,'子窗口源');
   
</script>

子窗口

<!--我是子窗口-->  
<div class="child"></div>
<script>
//子窗口给父窗口发消息
try {//放到trycatch里面,解决有些手机卡住报错问题
  window.top.postMessage(msg,'父窗口源');
      //嵌套一层使用window.top(parent),多层window.frameElement
      //使用top而不是window,top指向iframe最顶层窗口
  } catch (error) {

}

//监听父窗口信息
 window.addEventListener('message',function(event){
   ...
   })
</script>

注意:

父窗口给子窗口发信息,需要用iframe的contentWindow属性作为调用主体
子窗口给父窗口发的信息需要使用window.top,多层iframe使用window.frameElement

参考:

MDN:postMessage说明
兼容性