postMessage API
可以用来解决跨域页面通信的问题。因此,当初决定使用postMessage
解决书城和阅读器的通信问题。但是在使用过程中,还是有了波折。按照MDN
的文档,书城通过window.open
打开阅读器,同时通过readerReferer
(阅读器页面句柄)发送信息。阅读器则监听message
事件,获取数据。
// 代码大致如下 // 书城 const url = 'xxx' const readerReferer = window.open(url) readerReferer.postMessage({ dest: 'reader', name: 'bookName' }, url) // 阅读器 window.addEventListener('message', handleMessage) function handleMessage (e) { if (e.data.dest === 'reader') { console.log(e) } }
运行时发现,虽然成功打开了阅读器页面(不成功也难~~),但是阅读器页面始终没有接收到postMessage
的信息。网上关于这方面的资料也不多。但好歹找到一个靠谱的说法:postMessage
只管发送信息,但对方有没有接收到则不管。
原因找到了,阅读器从打开到监听事件是需要时间的,而书城的信息在此之前就发出了。
网上也提供了解决方法:发送方不立即发送信息,而是等待接收方告知可以发送了再发送信息。
// 修改后的大致代码 // 书城 const url = 'xxx' const readerReferer = window.open(url) window.addEventListener('message', canISend) function canISend(e) { if (e.data.from === 'reader') { readerReferer.postMessage({ dest: 'reader', name: 'bookName' }, url) } } // 阅读器 window.addEventListener('message', handleMessage) function handleMessage (e) { if (e.data.dest === 'reader') { console.log(e) } } window.opener.postMessage({ from: 'reader' }, '*')