网上关于serviceWorker
一般是用于做PWA
的,这里介绍的不是这个,如需了解,自行百度
原理:
serviceWorker
是一个独立于页面的,浏览器级别的线程
serviceWorker
线程可以与页面间通过addEventListener('message'
,postMessage
进行通信
serviceWorker
线程中可以获取到所有被此线程控制的浏览器窗口 self.clients.matchAll()
代码解析
- 首先页面中初始时要初始化
serviceWorker
:
navigator.serviceWorker
.register('serviceWorker.js', {
scope: '/',
})
.then(function(registration) {
...
- 每个页面进入时,通知
serviceWorker
有新页面打开了,并监听serviceWorker
的信息。
页面代码:
navigator.serviceWorker.controller.postMessage({
type: 'closeOtherClient',
})
navigator.serviceWorker.addEventListener('message', function(event) {
if (event.data.oprType && event.data.oprType === 'close') {
disconnectCBS.forEach(cb => cb())
}
})
serviceWorker.js
代码
serviceWorker
收到新窗口打开信号后,去通知其他所有页面执行关闭代码(比如页面上弹框提示用户,您的账号已在别处登陆)
this.addEventListener('message', function(event) {
const senderId = event.source ? event.source.id : 'unknow'
if (event.data.type === 'closeOtherClient') {
self.clients.matchAll().then(function(clients) {
if (clients && clients.length) {
clients.forEach(function(client) {
if (senderId !== client.id) {
client.postMessage({
oprType: 'close'
})
}
})
}
})
}
})
---------------------更新---------------------------
其实最近又发现一种更简单的方案:localstorage
上面使用serviceWorker
其实解决的就一个问题:浏览器内跨tab
通信
localstorage
实现跨tab
通信的原理是:
修改localstorage
时会在所属域名下的浏览器tab
内触发一个事件:storage
,可以通过window.addEventListener
监听此事件
所以如果想通知其他tab
,直接改下localstorage
,在其他tab
上监听到了此事件就可以做处理,这样就完成了跨tab
通信
其他方法
当然也可以设置一个定时器轮询localstorage
甚至cookie
等,在某tab
内改了本地存储,其他tab
内轮询后发现值变了就可以做处理。但这样就显得很low