1. 引入原因
postMessage是 HTML5新方法,它可以安全地实现跨源通信。它的初衷不是为了解决跨域
当一个窗口可以获取对另一个窗口的引用,然后在窗口上调用postMessage分发消息,接收消息的窗口可以根据需要处理接收到的消息
2. 语法
otherWindow.postMessage(message, targetOrigin, [transfer]);
otherWindow
其他窗口的一个引用,比如iframe的contentWindow属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames。
message
将要发送到其他 window的数据
targetOrigin
通过窗口的origin属性来指定哪些窗口能接收到消息事件,其值可以是字符串"*"(表示无限制)或者一个URI
transfer可选
是一串和message 同时传递的 Transferable 对象. 这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。
3. 监听message
通过message事件监听 window.addEventListener('message',(event)=>{})
event的常见属性:
data:发送的数据
orgin:发送数据的源
source:对发送数据的窗口对象的引用;
注意
- 使用origin和source属性验证发件人的身份
- 如果不希望从其他网站接收message,请不要为message事件添加任何事件侦听器
- 始终验证接收到的消息的语法
- 使用postMessage将数据发送到其他窗口时,始终指定精确的目标origin,而不是*
下面是qq.com中的index.html(对应qq.js)页面点击按钮跳转到frank.com的index.html(对应frank.js),这两个页面间的通信
// qq.js
btn.onclick = ()=>{
let data = {name:'aa'}
let page = window.open('http://frank.com:9999','frank')
page.postMessage(data,'http://frank.com:9999')
}
window.addEventListener('message', (e) => {
if(e.origin !== 'http://frank.com:9999')
return;
console.log(e.data)
})
// frank.js
window.addEventListener('message', (e) => {
if(e.origin !== 'http://qq.com:8888')
return;
console.log(e.data)
e.source.postMessage('Nice to see you', e.origin)
})
4. 使用场景
主要是当一个窗口可以获取对另一个窗口的引用,就可以实现通信,比如
- 源页面与通过
iframe新建的页面通信 - 源页面与通过
window.open新开的页面通信 - 源页面与通过
a标签跳转的页面通信
\