浏览器多窗口通信 BroadcastChannel

1,661 阅读2分钟

前言

最近在做一个项目的时候,产品要求可以打开多个浏览器窗口,后台发现多窗口间的localstorage数据同步偶尔会出现同步不及时的情况,所以就进行了一番google,也了解了一些方案,在此进行下分享

Storage Event

因为是 localstorage 数据同步不及时,所以最开始想到的就是 storage 事件。但是这个方案最后发现事件的触发频率太高太影响性能(加防抖又更新不及时);所以放弃此方案

window.postMessage 和 message 事件

window.postMessage() 方法可以安全地实现跨源通信。通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为https),端口号(443为https的默认值),以及主机 (两个页面的模数 Document.domain设置为相同的值) 时,这两个脚本才能相互通信。window.postMessage() 方法提供了一种受控机制来规避此限制,只要正确的使用,这种方法就很安全。

使用方法:

// pageA
const otherwindow = window.open(pageB);
otherwindow.postMessage('hello world'); 
// pageB
window.addEventListener('message', ev=>{
	// do something
})

otherwindow :其他窗口的一个引用,比如iframe的contentWindow属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames。

通过window.open打开的窗口一旦刷新,引用就消失了

BroadcastChannel+postMessage+message event

BroadcastChannel 接口代理了一个命名频道,可以让指定 origin 下的任意 browsing context 来订阅它。它允许同源的不同浏览器窗口,Tab页,frame或者 iframe 下的不同文档之间相互通信。通过触发一个 message 事件,消息可以广播到所有监听了该频道的 BroadcastChannel 对象。

使用方法:

// pageA
const channel = new BroadcastChannel("yto-message");
channel.postMessage('hello world');

// pageB
const channel = new BroadcastChannel("yto-message");
channel.addEventListener("message", ev => {
    // do something
})

兼容性

兼容性还行,除了safari不支持,其它现在浏览器都支持 在这里插入图片描述

至此浏览器多窗口间通信的文章就结束了,感谢你的耐心阅读!