初识postMessage

253 阅读2分钟

1. 引入原因

postMessageHTML5新方法,它可以安全地实现跨源通信。它的初衷不是为了解决跨域

当一个窗口可以获取对另一个窗口的引用,然后在窗口上调用postMessage分发消息,接收消息的窗口可以根据需要处理接收到的消息

2. 语法

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

otherWindow

其他窗口的一个引用,比如iframecontentWindow属性、执行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.comindex.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标签跳转的页面通信

\