SharedWorker 是浏览器中实现跨标签页、跨 iframe 共享同一工作线程的机制,通过消息通信配合 IndexedDB 等外部存储实现异步数据同步,需同源 HTTPS 环境,不支持 DOM 和 localStorage,Safari/iOS 兼容性差。

SharedWorker 是浏览器中实现跨标签页、跨 iframe 共享同一工作线程的机制,适合需要多个页面协同访问同一数据源或状态的场景。它本身不直接“共享数据”,而是通过消息通信 + 外部存储(如 IndexedDB、localStorage 或服务端)配合,实现逻辑上的异步数据同步。
SharedWorker 的基本结构与通信模型
SharedWorker 运行在独立线程中,生命周期独立于单个页面。每个使用它的页面通过 new SharedWorker() 获取一个 port 实例,再调用 port.start() 启动通信通道。所有页面都通过各自的 port 向 SharedWorker 发送消息,Worker 再统一响应或广播。
- SharedWorker 脚本必须是同源、HTTPS(或 localhost)环境下的独立 JS 文件,不能是内联脚本
- 页面与 Worker 之间是双向消息传递:页面
port.postMessage()→ Worker 的onconnect中获取 port → Worker 可向任意连接的 port 发送消息 - Worker 不具备 DOM 访问能力,也不能直接读写 localStorage;需借助其他机制持久化或同步状态
用 SharedWorker 协调跨标签页状态(例如登录态/计数器)
假设多个标签页需实时显示同一个用户计数器(如在线人数),SharedWorker 可作为“协调中心”统一维护数值,并将变更广播给所有连接的页面。
- Worker 内用一个变量(如
let count = 0)暂存状态,配合onconnect收集所有活跃 port - 页面发送
{ type: 'increment' }消息,Worker 更新 count 并遍历所有 port 调用port.postMessage({ count }) - 注意:仅靠内存变量无法应对 Worker 重启或浏览器休眠;关键状态应落地到 IndexedDB 或通过 WebSocket 同步到服务端
结合 IndexedDB 实现真正可靠的跨页数据共享
SharedWorker 本身不解决数据持久化问题。要确保标签页关闭再打开后仍能读取最新数据,应在 Worker 中封装对 IndexedDB 的统一访问逻辑。
立即学习“Java免费学习笔记(深入)”;
- Worker 初始化时打开数据库(如
openDB('shared-state', 1)),所有页面的读写请求都经由它代理 - 页面发送
{ type: 'update', key: 'theme', value: 'dark' },Worker 执行事务写入并广播变更 - 新打开的页面首次连接时,可主动请求
{ type: 'sync' },Worker 从 IndexedDB 读取全量数据返回 - 避免在 Worker 中做复杂计算或长时间阻塞操作,保持消息处理轻量
常见陷阱与注意事项
SharedWorker 行为在不同浏览器中略有差异,实际使用需谨慎验证。
- Chrome 和 Edge 支持良好;Safari 对 SharedWorker 支持有限(iOS 完全不支持),Firefox 需手动启用
dom.workers.sharedWorkers.enabled - 页面关闭时 port 会自动断开,但 Worker 不会立即终止——它会在所有 port 断开后延迟几秒销毁,期间仍可接收新连接
- 不能在 SharedWorker 中使用
fetch的 keepalive 模式,也不支持document.cookie或window相关 API - 调试困难:Chrome DevTools 的 Application → Shared Workers 面板可查看运行中的实例和消息流


















