postMessage API
发送数据:
otherWindow.postMessage(message, targetOrigin, [transfer]);
- otherWindow:
窗口的一个引用,比如iframe的contentWindow属性,执行window.open返回的窗口对象,或者是命名过的或数值索引的window.frames. - message:
要发送到其他窗口的数据,它将会被!结构化克隆算法序列化.这意味着你可以不受什么限制的将数据对象安全的传送给目标窗口而无需自己序列化. - targetOrigin:
通过窗口的origin属性来指定哪些窗口能接收到消息事件,指定后只有对应origin下的窗口才可以接收到消息,设置为通配符”*”表示可以发送到任何窗口,但通常处于安全性考虑不建议这么做.如果想要发送到与当前窗口同源的窗口,可设置为”/” - transfer | 可选属性:
是一串和message同时传递的Transferable对象,这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权.
场景:
父页面(index.html)用iframe嵌入了个子页面(iframePage.html),且里面加载了第三方项目,现在我们要实现父页面与子页面间的相互通信。
但由于同源策略,导致普通方法不行,所以这里我们采用HTML5里的postMessage
实现。
一、父页面向子页面传值
父页面index.html:
<!-- index.html -->
<body style="border:5px solid #333;">
<h1>this is index</h1>
<iframe src="./iframePage.html" id='myframe'></iframe>
</body>
<script type="text/javascript">
var iFrame = document.getElementById('myframe')
//iframe加载完毕后再发送消息,否则子页面接收不到message
iFrame.onload = function(){
//iframe加载完立即发送一条消息
iFrame.contentWindow.postMessage('MessageFromIndex1','*');
}
</script>
我们知道postMessage是挂载在window对象上的,所以等iframe加载完毕后,用iFrame.contentWindow获取到iframe的window对象,然后调用postMessage方法,相当于给子页面发送了一条消息。
子页面iframePage.html:
<!-- iframePage.html -->
<body style="border:5px solid #333;">
<h1>this is iframePage</h1>
</body>
<script type="text/javascript">
//回调函数
function receiveMessageFromIndex ( event ) {
console.log( 'receiveMessageFromIndex', event )
}
//监听message事件
window.addEventListener("message", receiveMessageFromIndex, false);
</script>
然后我们在index.html页面查看,发现子页面的receiveMessageFromIndex函数收到了来自于index.html页面传来的数据MessageFromIndex1
,所以成功了。
event
对象中的data
属性存放着我们从父页面传过来的数据
二、子页面向父页面传值
子页面iframePage.html:
<!-- iframePage.html -->
<body style="border:5px solid #333;">
<h1>this is iframePage</h1>
</body>
<script type="text/javascript">
//给父页面发送消息,data为对象
parent.postMessage( {msg: 'MessageFromIframePage'}, '*');
</script>
父页面index.html:
<!-- index.html -->
<body style="border:5px solid #333;">
<h1>this is index</h1>
<iframe src="./iframePage.html" id='myframe'></iframe>
</body>
<script type="text/javascript">
//回调函数
function receiveMessageFromIframePage (event) {
console.log('receiveMessageFromIframePage', event)
}
//监听message事件
window.addEventListener("message", receiveMessageFromIframePage, false);
</script>
然后我们在index.html页面查看,发现父页面的receiveMessageFromIndex函数收到了来自于子页面iframePage.html传来的数据receiveMessageFromIframePage
,所以成功了。