当浏览器同时打开多个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。
相关推荐
牧羊狼的狼33 分钟前
React 中的 HOC 和 Hooks
前端·javascript·react.js·hooks·高阶组件·hoc
知识分享小能手2 小时前
React学习教程,从入门到精通, React 属性(Props)语法知识点与案例详解(14)
前端·javascript·vue.js·学习·react.js·vue·react
魔云连洲2 小时前
深入解析:Vue与React的异步批处理更新机制
前端·vue.js·react.js
mCell3 小时前
JavaScript 的多线程能力:Worker
前端·javascript·浏览器
超级无敌攻城狮4 小时前
3 分钟学会!波浪文字动画超详细教程,从 0 到 1 实现「思考中 / 加载中」高级效果
前端
excel5 小时前
用 TensorFlow.js Node 实现猫图像识别(教学版逐步分解)
前端
gnip5 小时前
JavaScript事件流
前端·javascript
赵得C5 小时前
【前端技巧】Element Table 列标题如何优雅添加 Tooltip 提示?
前端·elementui·vue·table组件
wow_DG6 小时前
【Vue2 ✨】Vue2 入门之旅 · 进阶篇(一):响应式原理
前端·javascript·vue.js
weixin_456904276 小时前
UserManagement.vue和Profile.vue详细解释
前端·javascript·vue.js