Shared Worker 可实现同源页面间轻量级跨标签消息广播。它通过独立脚本监听连接、维护 port 列表,将任一页面发送的消息遍历推送给其他所有页面,无需服务器、轮询或 WebSocket,但存在浏览器兼容性及无序无ACK等限制。

Shared Worker 可以让多个页面(同源)共享同一个 Worker 线程,天然适合做跨标签页/窗口的轻量级消息中转。它不依赖服务器,纯前端即可实现简单聊天消息分发——比如你在 A 标签页发一条消息,B、C 标签页实时收到,无需轮询或 WebSocket。
一、Shared Worker 的基本结构
Shared Worker 是一个独立于页面的脚本,所有页面通过 new SharedWorker() 连接它;Worker 内部用 onconnect 监听连接,每个连接对应一个 port,用于双向通信。
关键点:
- 必须同源(协议 + 域名 + 端口完全一致)
- Worker 脚本需单独托管为一个 .js 文件(不能是内联脚本)
- 页面与 Worker 通信必须调用
port.start()后才能收发消息
二、实现跨页面消息广播
Worker 不保存状态,只做“中继”:任一页面发来的消息,Worker 收到后遍历所有已连接的 port,逐个 postMessage 推送出去(自己除外)。
Shared Worker 脚本(chat-worker.js)示例:
let ports = [];
self.onconnect = function(e) {
const port = e.ports[0];
ports.push(port);
port.onmessage = function(e) {
const { type, payload } = e.data;
if (type === 'send') {
// 广播给其他所有页面(排除发送者)
ports.forEach(p => {
if (p !== port && p.postMessage) {
p.postMessage({ type: 'receive', payload });
}
});
}
};
port.start(); // 必须调用
};三、页面端接入与使用
每个聊天页面引入 Shared Worker,并监听消息、发送消息:
// 初始化 Shared Worker
const worker = new SharedWorker('chat-worker.js');
worker.port.onmessage = function(e) {
if (e.data.type === 'receive') {
console.log('收到消息:', e.data.payload); // 渲染到聊天列表
}
};
worker.port.start();
// 发送消息(例如点击发送按钮时)
function sendMessage(text) {
worker.port.postMessage({
type: 'send',
payload: {
text,
from: window.location.href.split('/').pop() || 'tab',
time: new Date().toLocaleTimeString()
}
});
}注意:
- 多个页面共用同一个 Worker 实例,不需要重复 new(浏览器自动复用)
- 页面关闭时,对应的 port 会自动断开,Worker 中的 ports 数组不会自动清理,建议加
port.onclose移除引用(可选,小项目可忽略)
四、补充说明与限制
Shared Worker 适合原型、内部工具或轻量协作场景,但有明确局限:
- 不支持 Service Worker 那样的离线缓存或网络拦截
- 无法访问 DOM、
document或window,只能处理纯数据 - Chrome/Firefox/Edge 支持良好,Safari 对 Shared Worker 支持较晚(iOS 16.4+,macOS 13.3+),生产环境需降级兜底(如 localStorage + storage 事件)
- 消息无序、无 ACK、无重试,不适合高可靠性场景
若需持久化、历史记录或用户身份管理,仍需后端配合。但仅做“当前在线标签页间传话”,Shared Worker 简洁有效。










