【JS Web API】SharedWorker 比 Broadcast Channel 更高级的跨标签页通信 API

2026-05-04 10:39:52

SharedWorker 介绍

SharedWorker 和 Broadcast Channel 都可用于处理跨标签页通信,但二者在功能与适用场景上存在显著差异:

Broadcast Channel 类似于一个公共广播系统,只能进行“一对多”的消息发布。它无法指定特定的接收者,也无法控制消息的接收顺序,更无法接收来自监听方的反馈或响应。换句话说,它只支持单向、无状态的消息广播。

SharedWorker 则不仅具备广播消息的能力,还能实现更精细的控制。它可以 指定特定的对象接收消息,支持 按顺序传递消息,甚至能够 接收并处理来自接收方的反馈信息,从而实现双向、有状态的通信。

SharedWorker 广播消息示例

广播消息: 一个页面发送消息,让其它访问相同网站的页面接收消息。

写一个 SharedWorker 脚本 sw.js 文件,维护一个端口池(port pool),当某个页面发送消息时,Worker 遍历所有已连接的端口,将消息转发给每一个端口,从而实现广播效果。

// 存储所有连接的端口
const connections = []

// 监听到标签页连接 SharedWorker 会进入该方法
self.onconnect = (e) => {
    const port = e.ports[0]
    connections.push(port)
    console.log('新客户端连接,当前连接数:', connections.length)
    
    // 监听到标签页发送消息会进入该方法
    port.onmessage = (event) => {
        // 广播消息给所有连接的页面
        connections.forEach(p => {
            p.postMessage({
                from: 'Broadcast',
                data: event.data,  // event.data 接收消息
                timestamp: Date.now()
            })
        })
    }
    
    port.start()
}

写一个 index.html 文件用于测试

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>SharedWorker 广播 - 发送页面</h1>
    <input type="text" id="messageInput" placeholder="输入要广播的消息">
    <button onclick="broadcastMessage()">发送广播</button>
    <div id="receivedMessages"></div>

    <script>
        // 创建 SharedWorker
        const worker = new SharedWorker('./sw.js')
        console.log('worker', worker)
        worker.port.start()
        
        // 发送广播消息
        function broadcastMessage() {
            const msg = document.getElementById('messageInput').value
            worker.port.postMessage(msg)
            document.getElementById('messageInput').value = ''
        }
        
        // 接收广播消息
        worker.port.onmessage = (e) => {
            const messagesDiv = document.getElementById('receivedMessages')
            messagesDiv.innerHTML += `<p>收到广播: ${e.data.data}</p>`
        }
    </script>
</body>
</html>

到目前为止,准备工作已经完成。需要注意的是,不能直接在浏览器中通过 file:// 协议打开 HTML 文件,因为 SharedWorker 必须在 HTTPS 或 localhost 环境下才能正常注册。

接下来,我们使用 http-server 创建一个本地 Web 服务器环境:

$ npx http-server . -p 8080

然后在浏览器中打开两个标签页,均访问 http://localhost:8080/index.html。在其中一个标签页中修改文本框的值并点击“发送广播”,在另一个标签页中可以看到消息已经成功更新。

补充说明:由于 SharedWorker 中的 console.log 不会显示在页面的控制台中,需要通过以下方式进行调试:在浏览器地址栏访问 chrome://inspect/#workers,在该页面中可以查看当前已创建的 SharedWorker。点击其中的 inspect 链接,即可进入独立的调试控制台。

返回首页

本文总阅读量  次
皖ICP备17026209号-3
总访问量: 
总访客量: