使用serviceWorker做前端的單點(diǎn)登陸

網(wǎng)上關(guān)于serviceWorker一般是用于做PWA的,這里介紹的不是這個(gè),如需了解,自行百度

原理:

serviceWorker是一個(gè)獨(dú)立于頁(yè)面的,瀏覽器級(jí)別的線程

serviceWorker線程可以與頁(yè)面間通過(guò)addEventListener('message',postMessage進(jìn)行通信

serviceWorker線程中可以獲取到所有被此線程控制的瀏覽器窗口 self.clients.matchAll()

代碼解析

  1. 首先頁(yè)面中初始時(shí)要初始化serviceWorker
navigator.serviceWorker
      .register('serviceWorker.js', {
        scope: '/',
      })
      .then(function(registration) {
        if (config && config.onRegister) {
          config.onRegister(registration)
        }
        ...
  1. 每個(gè)頁(yè)面進(jìn)入時(shí),通知serviceWorker有新頁(yè)面打開了,并監(jiān)聽serviceWorker的信息。

頁(yè)面代碼:

navigator.serviceWorker.controller.postMessage({
    type: 'closeOtherClient',
 })

if (event.data.oprType && event.data.oprType === 'close') {
    disconnectCBS.forEach(cb => cb())
}
  1. serviceWorker.js代碼

serviceWorker收到新窗口打開信號(hào)后,去通知其他所有頁(yè)面執(zhí)行關(guān)閉代碼(比如頁(yè)面上彈框提示用戶,您的賬號(hào)已在別處登陸)

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'
            })
          }
        })
      }
    })
  }
})
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容