背景
在浏览器中每个页面都运行在单独的进程中,如何实现页面间的通信?
实现方案
BroadCastChannel
BroadcastChannel 接口代理了一个命名频道,可以让指定 origin 下的任意 browsing context 来订阅它。它允许同源的不同浏览器窗口,Tab 页,frame 或者 iframe 下的不同文档之间相互通信。通过触发一个 message
事件,消息可以广播到所有监听了该频道的 BroadcastChannel
对象。
- 构建一个实例
1
| const bc = new BroadcastChannel('channel')
|
- 调用
postMessage
发送消息
- 分别监听
onmessage
和 onmessageerror
事件来接收数据和错误消息
1 2 3 4 5 6
| bc.onmessage = function (e) { } bc.onmessageerror = function (e) { }
|
- 调用
close
关闭通道,并销毁 BroadcastChannel
对象
localStorage 实现
当前页面使用的 storage
被其他页面修改时会触发 StorageEvent
事件
- 在源页面设置值触发事件
1
| localStorage.setItem('newValue', 'new')
|
- 在接收页面监听
storage
事件以实现通信
1 2 3 4
| window.addEventListener('storage', function (e) { })
|
其它方案
Service Worker
: 一个可以长期运行在后台的 Worker,能够实现与页面的双向通信。
Shared Worker
: Worker 家族的另一个成员。普通的 Worker 之间是独立运行、数据互不相通;而多个 Tab 注册的 Shared Worker 则可以实现数据共享。
IndexedDB
: 数据存储技术
window.open + window.opener
: 当我们使用 window.open 打开页面时,方法会返回一个被打开页面 window 的引用。而在未显示指定 no opener 时,被打开的页面可以通过 window.opener 获取到打开它的页面的引用 —— 通过这种方式我们就将这些页面建立起了联系(一种树形结构)。
visibilitychange
: 当其选项卡的内容变得可见或被隐藏时,会在文档上触发 visibilitychange (能见度更改)事件。
参考