当浏览器同时打开多个tab时,前端有哪些方式进行通讯和数据共享?

核心想法是找到一个通用的第三方。这个第三方可以同时联系到标签一、标签二。(同样的逻辑,可以参考 vuex 或 pinia)

  1. BroadcastChannel
  • 适用场景: 同源的多个 Tab 需要简单高效的消息广播
  • 实现原理: BroadcastChannel 提供了一个发布/订阅模型,允许同源页面间传递消息。

Tab1 发送消息:

js 复制代码
const channel = new BroadcastChannel('my_channel');
channel.postMessage('Hi from Tab 1');

Tab2 发送消息:

js 复制代码
const channel = new BroadcastChannel('my_channel');
channel.onmessage = (event)=>{
  console.log('Received message:', event.data);
}
  • 优点: 简单易用,支持多 Tab 广播。
  • 限制: 需要页面同源,浏览器支持范围有限(现代浏览器支持良好)。
  1. LocalStorage + StorageEvent
  • 适用场景: 同源页面间低频、简单的状态同步。
  • 实现原理: localStorage 数据更新时,其他 Tab 会触发 storage 事件,页面可监听到数据变化。

Tab1 写入消息:

js 复制代码
localStorage.setItem('key', 'hi from Tab 1');

Tab2 监听变化:

js 复制代码
window.addEventListener('storage', (event)=>{
  if(event.key === 'key'){
    console.log('Received message:', event.newValue);
  }
})
  1. Service Worker
  • 适用场景: 需要多个 Tab 与后台服务共享信息或实现双向通信
  • 实现原理: 通过 Service Worker 的消息通道,Tab 可以与 Service Worker 通信,Service Worker 也可以作为中间层实现多个 Tab 间的消息转发。

Tab 发送消息到 Service Worker:

js 复制代码
navigator.serviceWorker.controller.postMessage('hi from Tab');

Service Worker 监听消息并广播:

js 复制代码
self.addEventListener('message', (event)=>{
  self.clients.matchAll().then(clients =>{
    clients.forEach(client => client.postMessage(event.data));
  })
})

Tab 接收消息:

js 复制代码
navigator.serviceWorker.addEventListener('message', (event) => {
  console.log('Received message:', event.data);
});
  1. SharedWorker
  • 适用场景: 需要多个同源 Tab 长连接并共享状态。
  • 实现原理: SharedWorker 允许多个 Tab 共享一个 Worker 线程,并通过消息通道通信。

SharedWorker文件(worker.js):

js 复制代码
onconnect = function(event) {
  const port = event.ports[0];
  port.onmessage = (e) => {
    console.log('Received from Tab:', e.data);
    port.postMessage('Message received in Worker');
  };
};

Tab 使用 SharedWorker:

js 复制代码
const worker = new SharedWorker('worker.js');
worker.port.onmessage = (event) => {
  console.log('Received from Worker:', event.data);
};
worker.port.postMessage('hi from Tab');
  • 优点: 支持双向通信,性能较好。
  • 限制: 需要同源,较少应用于简单场景,现代浏览器支持较好。
  1. WebSocket
  • 适用场景: 跨域或需要实时通信的复杂场景(不仅限于浏览器 Tab 通信)。
  • 实现原理: 多个 Tab 通过 WebSocket 连接同一个服务端,服务端转发消息。
js 复制代码
const socket = new WebSocket('wss://example.com/socket');
socket.onmessage = (event) => {
  console.log('Received message:', event.data);
};
socket.send('hi from Tab');
  • 优点: 不受同源限制,支持实时通信。
  • 限制: 需要服务端支持,需额外开发和维护。
  1. PostMessage + window.opener
  • 适用场景: 当 Tab 通过 window.open 打开的,支持父窗口与子窗口之间的通信。
  • 实现原理: 通过 postMessage 方法向特定窗口发送消息。

父窗口发送消息给子窗口:

js 复制代码
const childWindow = window.open('child.html');
childWindow.postMessage('hi from Parent', '*');

子窗口接收消息:

js 复制代码
window.addEventListener('message', (event) => {
  console.log('Received message:', event.data);
});
  • 优点: 灵活支持跨域通信。
  • 限制: 仅限于父子窗口,不能广播到多个Tab。
相关推荐
半点寒12W12 分钟前
微信小程序实现路由拦截的方法
前端
某公司摸鱼前端1 小时前
uniapp socket 封装 (可拿去直接用)
前端·javascript·websocket·uni-app
要加油哦~1 小时前
vue | 插件 | 移动文件的插件 —— move-file-cli 插件 的安装与使用
前端·javascript·vue.js
小林学习编程1 小时前
Springboot + vue + uni-app小程序web端全套家具商场
前端·vue.js·spring boot
柳鲲鹏1 小时前
WINDOWS最快布署WEB服务器:apache2
服务器·前端·windows
weixin-a153003083162 小时前
【playwright篇】教程(十七)[html元素知识]
java·前端·html
ai小鬼头3 小时前
AIStarter最新版怎么卸载AI项目?一键删除操作指南(附路径设置技巧)
前端·后端·github
一只叫煤球的猫3 小时前
普通程序员,从开发到管理岗,为什么我越升职越痛苦?
前端·后端·全栈
vvilkim3 小时前
Electron 自动更新机制详解:实现无缝应用升级
前端·javascript·electron
vvilkim3 小时前
Electron 应用中的内容安全策略 (CSP) 全面指南
前端·javascript·electron