Shared Worker怎么用?多个浏览器标签页共享数据的实现方法
2026-09-06 3 0
在传统的 JavaScript 开发中,每个浏览器标签页都有独立的 JavaScript 运行环境。如果希望用户打开多个标签页后,让这些页面共享登录状态、计数器、缓存数据或实时消息,通常需要借助 localStorage、BroadcastChannel 等 API。
Shared Worker 则提供了另一种方案:多个同源页面可以连接到同一个 Worker,由这个 Worker 在内存中维护一份共享数据,并通过 MessagePort 与不同标签页通信。按照 MDN 当前资料,Shared Worker 在 2026 年 5 月起被标记为 Baseline 2026,但旧设备和浏览器仍可能存在兼容性差异。
Shared Worker是什么?
普通 Worker 通常由一个页面独占,而 SharedWorker 可以被多个窗口、标签页、iframe 或其他 Worker 访问。不过,这些页面必须属于完全相同的 Origin,也就是协议、域名和端口都一致。
它的基本工作流程可以理解为:
标签页A ──┐
标签页B ──┼── Shared Worker ── 共享数据
标签页C ──┘
每个页面通过 SharedWorker.port 获得一个 MessagePort,然后使用 postMessage() 向 Worker 发送数据,再通过 message 事件接收结果。
创建 Shared Worker
首先创建 shared-worker.js:
const clients = [];
let count = 0;
self.onconnect = function (event) {
const port = event.ports[0];
clients.push(port);
port.onmessage = function (event) {
if (event.data === "get") {
port.postMessage(count);
}
if (event.data === "increment") {
count++;
clients.forEach(client => {
client.postMessage(count);
});
}
};
port.start();
};
这里的关键是 onconnect。每当新的浏览器标签页连接 Shared Worker 时,都会触发连接事件,并可以通过 event.ports[0] 获取当前页面对应的通信端口。
网页如何连接 Shared Worker?
在页面 JavaScript 中创建 Worker:
const worker = new SharedWorker("shared-worker.js");
worker.port.start();
worker.port.onmessage = event => {
document.querySelector("#count").textContent = event.data;
};
document.querySelector("#add").onclick = () => {
worker.port.postMessage("increment");
};
worker.port.postMessage("get");
HTML 可以简单写成:
<button id="add">+1</button>
<div>当前数量:<span id="count">0</span></div>
现在同时打开两个相同网站的标签页,在其中一个页面点击 +1,Shared Worker 会修改共享的 count,然后遍历所有已经连接的 MessagePort,将最新数据推送给其他标签页。
这样就实现了多个浏览器标签页共享内存数据。
Shared Worker适合哪些场景?
Shared Worker比较适合需要长期保持多个页面状态同步的应用,例如多个标签页共享在线用户状态、统一管理 WebSocket 连接、共享实时数据、减少重复网络请求,以及实现多个页面之间的任务协调。
例如,一个网站同时打开首页、订单页和消息页,可以让 Shared Worker 维护唯一的 WebSocket 连接,再把服务器推送的数据分发给多个页面,从而避免每个标签页都建立独立连接。
需要注意的是,Worker中的数据并不是持久化数据库。浏览器关闭相关页面、Worker生命周期结束后,内存数据也可能消失。如果需要长期保存数据,仍然应该使用 IndexedDB 等存储方案。
Shared Worker和BroadcastChannel怎么选?
如果只是需要让多个标签页简单地互相发送通知,BroadcastChannel 往往更加直接。它允许同源的不同窗口、标签页、iframe 和 Worker 通过命名频道广播消息,而且目前浏览器支持度已经比较成熟。
而 Shared Worker 更适合集中管理共享状态和共享资源。例如多个页面共同使用一个 WebSocket、统一维护缓存或执行后台计算,此时 Shared Worker 的优势更加明显。
总体来说,简单消息同步优先考虑 BroadcastChannel。需要一个真正的共享运行环境和统一状态管理,则可以考虑 SharedWorker。
使用Shared Worker的注意事项
Shared Worker最大的前提是同源,不同协议、域名或端口的页面不能直接共享同一个 Worker。另外,Worker脚本本身也需要正确部署,并注意 CSP 和脚本来源安全问题。MDN也特别提醒,SharedWorker() 加载的脚本会被执行,因此动态传入不可信 URL 存在安全风险。
对于2026年的前端项目,如果目标浏览器环境明确支持 Shared Worker,可以把它作为多标签页共享状态、统一连接和实时通信的一种原生方案。如果只需要简单的标签页消息同步,则 BroadcastChannel 通常更加轻量。