多个浏览器标签页之间如何密谋?【前端实现】

299 阅读2分钟

实现浏览器多标签页之间通信

需求场景:浏览器多个标签页之间需要进行数据通信。

方法1:localStorage实现通信

localStorage的特点:

  • 同域共享存储空间
  • 持久化将数据存储来浏览器
  • 提供事件监听localStorage变化

简单实现:

A标签页:

window.addEventListener("storage", (e) => { 
    console.info("localStorage发生变化:", e) 
})

B标签页:

localStorage.setItem("data", '100');

注意:

  • 同域共享,如果多个标签页跨域了,那么数据将无法共享(域名、端口、协议)。
  • 使用storage事件监听localStorage变化,也可以直接通过localStorage.getItem()获取数据。

方法2:使用websocket

原理:广播和接收。

简单实现:

搭建websocket服务器实现多标签页通信,实现比较复杂且需要增加一个服务器导致增加了总体服务器压力。

注意:

  • 没有同源共享策略,即可实现跨域共享。
  • 不建议使用websocket来进行多标签页通信,因为使用websocket会增加服务器的负担。

方法3:使用WebWorker中的SharedWorker

SharedWorker是WebWorker中的一种。

原理:广播和接收。

简单实现:

// worker.js  ---初始化配置文件
const set = new Set()
onconnect = event => {
  const port = event.ports[0]
  set.add(port)


  // 接收信息
  port.onmessage = e => {
    // 广播信息
    set.forEach(p => {
      p.postMessage(e.data)
    })
  }


  // 发送信息
  port.postMessage("worker广播信息")
}

A标签页:

  const worker = new SharedWorker('./worker.js')
  
  worker.port.onmessage = e => {
    console.info("pageA收到消息", e.data)
  }

B标签页:

  const worker = new SharedWorker('./worker.js')
  
  worker.port.postMessage(`100`)

注意:

  • 有同源共享策略限制,跨域不共享。
  • SharedWorker缺点:调试不太方便、兼容性不太好(IE已死,推荐使用)。

方法4:使用cookie + setInterval实现

cookie特点:

  • 跨域不共享
  • 具有存储空间限制
  • 请求会自动携带cookie

简单实现:

A标签页:

  setInterval(() => {
    //加入定时器,让函数每一秒就调用一次,实现页面刷新
    console.log("cookie",document.cookie)
  }, 1000);
  • 为什么使用setInterval?因为cookie本身没有回调事件监听cookie的变化,需要使用setInterval实现。

B标签页:

  document.cookie = `100`

注意:

  • 有同源共享策略限制,跨域不共享。
  • 能够传输的数据太小(4k),不推荐使用。

传送门

你是如何实现浏览器多标签页之间通信的?