不同窗口通信的postMessage方法的详解

窗口之间的通信,如果是不同域的,会受到浏览器的同源策略的限制,这篇文章介绍的postMessage方法可以解决这个问题

postMessage是window的属性,一般用于跨域窗口之间的通信

我们直接从实例中来学这个方法, 这样会理解的更深

我们现在要实现 https://v.qq.com/和https://ke.qq.com之间的通信

在v.qq.com的控制台中输入下面代码,打开ke.qq.com

不同窗口通信的postMessage方法的详解_第1张图片

为新开窗口注册message事件

接下来用postMessage方法给新窗口发送消息

查看新窗口的控制台

根据打印信息,说明新窗口已收到v.qq.com发来的信息

接下来,我们把message事件的回调函数改下,在我们确定收到v.qq.com的信息后,回复'world'

看上面的截图,新窗口确实在收到v.qq.com发来的信息后,回复了World

讲完了基本的用法,接下来说下注意点

1.如果postMessage的第二个参数和调用它的窗口对象的location.origin不一致,信息会发送不出去,只有一致了才发送的出去

我们来测试一下

执行后没回复,并且在ke.qq.com窗口中报错,错误信息就是说target origin的值为‘http://v.qq.com’和 ke的域不一样,导致postMessage执行失败

上述是协议不一致引起的,如果域名,端口号不一致也会造成这个错误

 

2.postMessage第二个参数可以用*来代替,效果也是一样的,但是不建议这样做,因为又被恶意网站窃取信息的危险,尤其但你发送密码之类敏感信息的时候,一定要明确指定targetOrigin参数,不能用*代替

我们来试下效果

说明也是的

3.在web worker中也用到了这个方法,但是第二个参数是忽略的

// worker.js
let name = 'yewenjun'
console.log(self)
self.addEventListener('message', (event)=>{
    console.log(`${event.data} from ${event.origin}`)
    // do something
    // ...
    self.postMessage('done')
    self.close()
})
// main.js
let worker = new Worker('js/worker.js')
worker.postMessage('hello World!')
worker.addEventListener('message', (event)=>{
    console.log(`${event.data} from ${event.origin}`)
})

web worker主要用来执行长任务,用新开的worker线程来执行长任务,防止主线程的阻塞

你可能感兴趣的:(javaScript)