BroadcastChannel
是一种用于在同一来源(同一协议、主机名和端口号)下不同浏览器上下文(如标签页、iframe、Worker、Service Worker)之间进行消息广播的 API。它提供了一种简便、可靠的方法来实现跨上下文的实时通讯。
BroadcastChannel
创建的实例代表一个特定的广播频道,所有监听该频道的上下文都能接收该频道发送的消息。postMessage
方法发送消息,所有监听该频道的上下文都会收到消息。onmessage
事件处理器接收和处理来自该频道的消息。在多个上下文中使用相同的频道名称创建 BroadcastChannel
实例。
const channel = new BroadcastChannel('my_channel');
在任意一个上下文中,通过 postMessage
方法向频道发送消息。
channel.postMessage('Hello from one context');
在其他上下文中,通过监听 onmessage
事件接收消息。
channel.onmessage = (event) => {
console.log('Received message:', event.data);
};
以下是 BroadcastChannel
实现不同标签页之间通讯的工作流程图:
┌──────────────────────┐ ┌──────────────────────┐
│ Page A │ │ Page B │
│ │ │ │
│ BroadcastChannel │ │ BroadcastChannel │
│ 'my_channel' │ │ 'my_channel' │
│ │ │ │ │ │
│ ▼ │ │ ▼ │
│ channel.postMessage │ │ │
│ ('Hello from A') │────────────────│ channel.onmessage │
│ │ │ event.data === │
│ │ │ 'Hello from A' │
│ │ │ │
└──────────────────────┘ └──────────────────────┘
DOCTYPE html>
<html>
<head>
<title>Page Atitle>
head>
<body>
<button onclick="sendMessage()">Send Messagebutton>
<script>
const channel = new BroadcastChannel('my_channel');
function sendMessage() {
channel.postMessage('Hello from Page A');
}
script>
body>
html>
DOCTYPE html>
<html>
<head>
<title>Page Btitle>
head>
<body>
<script>
const channel = new BroadcastChannel('my_channel');
channel.onmessage = (event) => {
console.log('Received message in Page B:', event.data);
};
script>
body>
html>
当用户在一个标签页中登录或注销,其他打开同一应用的标签页需要同步登录状态。
// 标签页 A 中用户登录
const authChannel = new BroadcastChannel('auth_channel');
authChannel.postMessage('User logged in');
// 其他标签页中监听登录状态变化
authChannel.onmessage = (event) => {
if (event.data === 'User logged in') {
// 同步用户登录状态
}
};
在一个标签页中更新数据,其他标签页需要实时显示更新结果,例如股票行情、实时聊天消息等。
// 标签页 A 中更新数据
const dataChannel = new BroadcastChannel('data_channel');
dataChannel.postMessage({ type: 'update', data: 'New data' });
// 其他标签页中监听数据更新
dataChannel.onmessage = (event) => {
if (event.data.type === 'update') {
console.log('Received data update:', event.data.data);
// 更新界面显示
}
};
用户在多个标签页中打开同一个应用,需要各标签页协同工作。例如,在一个标签页中填写表单,另一个标签页显示表单预览。
// 标签页 A 中填写表单并广播数据
const formChannel = new BroadcastChannel('form_channel');
document.getElementById('formInput').addEventListener('input', (event) => {
formChannel.postMessage({ type: 'form_update', value: event.target.value });
});
// 标签页 B 中接收表单数据并显示预览
formChannel.onmessage = (event) => {
if (event.data.type === 'form_update') {
document.getElementById('formPreview').innerText = event.data.value;
}
};
BroadcastChannel
提供了一种简单而强大的方法,用于在同源的不同浏览器上下文之间进行实时通讯。它特别适合需要即时同步数据的应用场景,如用户登录状态同步、实时数据更新和多标签页协同工作。通过掌握 BroadcastChannel
的使用方法,开发者可以大大提升 web 应用的用户体验和功能。