当浏览器同时打开多个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。
相关推荐
独立开阀者_FwtCoder1 分钟前
TypeScript 杀疯了,开发 AI 应用新趋势!
前端·javascript·github
汪子熙6 分钟前
QRCode.js:一款轻量级、跨浏览器的 JavaScript 二维码生成库
前端·javascript·面试
Mintopia7 分钟前
Three.js 阴影映射:光影魔术师的神秘配方
前端·javascript·three.js
sztomarch8 分钟前
Router-Routing
linux·运维·服务器·前端·网络
Mintopia9 分钟前
计算机图形学法线贴图(Normal Mapping)教学:让平面物体 “穿上魔法铠甲”
前端·javascript·计算机图形学
独立开阀者_FwtCoder9 分钟前
Node.js 官方发布新工具,助力稳定 TypeScript 支持!
前端·javascript·vue.js
洛千陨10 分钟前
vue + LogicFlow 实现流程图展示
前端·javascript
xcLeigh11 分钟前
HTML5实现好看的邀请函网页源码
前端·html
小小神仙11 分钟前
JSCommon系列 - 前端常用工具库集合
前端·javascript·面试
cv也要开心12 分钟前
Commander.js 完全掌握——构建优雅CLI
前端·javascript