日常开发中可能遇到一种需求,需要我们在某个页面执行了某些操作,同时要同步操作到另一个页面,比如访问某音乐网站,打开某首音乐新开一个页面听歌,再回到原来的页面切换其它歌时,播放音乐的页面也要同步切换到对应的歌曲。
Broadcast Channel API
Broadcast Channel API 可以在不同的浏览器标签页之间进行消息通信。通过 Broadcast Channel API,你可以创建一个通道(channel),并在不同的标签页中发送和接收消息。
发送消息
const channel = new BroadcastChannel('myChannel');
channel.postMessage({ message: 'Hello' })
接收消息
const channel = new BroadcastChannel('myChannel');
channel.addEventListener('message', function(event) {
const receivedData = event.data;
// 处理接收到的数据
console.log(receivedData);
});
关闭连接
channel.close();
SharedWorker
SharedWorker 是一个在不同标签页之间共享执行环境的后台线程,可以实现多个标签页之间的通信。不同的标签页可以通过 SharedWorker 发送和接收消息。同一个url 的 worker js 只会创建一个 sharedWorker,其他页面再使用同样的url创建 sharedWorker,会复用已创建的 worker,这个worker由那几个页面共享。
// worker.js
var clients = [];
onconnect = function(e) {
var port = e.ports[0];
clients.push(port);
port.addEventListener("message", function(e) {
for (var i = 0; i < clients.length; i++) {
var eElement = clients[i];
eElement.postMessage(e.data);
}
});
port.start();
};
发送消息
const worker = new SharedWorker('worker.js');
worker.port.postMessage({ message: 'Hello' });
接收消息
const worker = new SharedWorker('worker.js');
worker.port.addEventListener('message', function(event) {
const receivedData = event.data;
// 处理接收到的数据
console.log(receivedData);
});
需要注意的是,跨域的情况下,可能需要使用其他的技术手段,比如 WebSocket、服务器端消息推送等。
BroadcastChannel 和 SharedWorker 的区别:
- 通信范围:BroadcastChannel 可以在同一个浏览器中的不同标签页之间进行消息通信,而 SharedWorker 可以在不同的标签页之间共享执行环境,也可以在不同的窗口或浏览器中进行通信。
- 数据广播:BroadcastChannel 只能在同一个浏览器中的标签页之间广播消息,而 SharedWorker 可以将消息传递给所有连接到同一个 SharedWorker 的窗口或标签页。
- 共享数据:SharedWorker 允许在每个连接的标签页之间共享数据,标签页可以通过 SharedWorker 共享同一个状态、变量或对象,这可以用于共享状态或实现共享功能。而 BroadcastChannel 只是用于传递简单的消息,不具有共享数据的能力。
- 生命周期:SharedWorker 是一个在后台运行的线程,会在没有连接的标签页时继续存在,而 BroadcastChannel 只在有连接的标签页时才有效。
因此,BroadcastChannel 更适合于在同一个浏览器的不同标签页之间进行简单的消息通信,而 SharedWorker 则更适合共享状态、数据和功能,可以实现更复杂的跨标签页或跨窗口的通信需求。