## 举个例子就是,假如一个浏览器打开了多个相同的窗口,其中某个窗口调用了编辑接口,数据更新了,其他的窗口数据怎么自动更新,不能手动刷新页面
http://localhost:8080 的两个标签页),大部分原生 API 可直接通信;http://a.com 和 http://b.com),仅少数 API 支持(需显式授权)1.LocalStorage 监听(最常用)
原理:
storage 事件(当前修改窗口不触发),监听该事件即可获取数据// 窗口A(编辑数据或其他更新操作后)
localStorage.setItem('dataUpdated', JSON.stringify({
type: 'message',
content: 'Hello 窗口B'
}));
// 窗口B(监听变化)
window.addEventListener('storage', (e) => {
if (e.key === 'dataUpdated') {
const data = JSON.parse(e.newValue);
console.log('收到消息:', data.content); // 输出:Hello 窗口B
// 重新获取数据
refresh();
}
});| 特性 | 说明 |
|---|---|
| 优点 | 兼容性最好(IE8+)、实现简单、数据持久化 |
| 缺点 | 只能传字符串、同值不触发、有大小限制(5-10MB) |
| 场景 | 登录状态同步、主题切换、购物车数量 |
原理:
new BroadcastChannel('my-channel'));
// 窗口A
const channel = new BroadcastChannel('data-update');
channel.postMessage({ type: 'dataUpdated' });
//接收方 窗口B
const channel = new BroadcastChannel('data-update');
channel.onmessage = (e) => {
if (e.data.type === 'dataUpdated') {
refresh();
}
};| 特性 | 说明 |
|---|---|
| 优点 | API 极简、性能好、自动管理生命周期 |
| 缺点 | 不支持 IE、无状态存储 |
| 场景 | 跨标签页消息广播、实时通知同步 |
原理:
// worker.js - 广播给所有窗口
const ports = [];
self.addEventListener('connect', (e) => {
const port = e.ports[0];
ports.push(port);
port.onmessage = (msg) => {
// 广播给所有窗口(包括自己)
ports.forEach(p => p.postMessage(msg.data));
};
port.start();
});
// 页面
const worker = new SharedWorker('worker.js');
worker.port.start();
worker.port.onmessage = (e) => console.log('收到:', e.data);
worker.port.postMessage('hello');| 特性 | 说明 |
|---|---|
| 优点 | 共享连接、内存、定时器,性能最好 |
| 缺点 | API 复杂、调试困难 |
| 场景 | WebSocket连接复用、全局状态管理、统一缓存 |
需要跨窗口通信?
│
├─ 1. 是否需要共享持续的连接或状态?
│ ├─ 是 → **SharedWorker** (最强大,适合复杂场景)
│ └─ 否 → 继续判断
│
├─ 2. 是否需要支持老旧的 IE 浏览器?
│ ├─ 是 → **localStorage + storage 事件** (兼容性最佳)
│ └─ 否 → 继续判断
│
└─ 3. 只是简单、快速的页面间消息广播?
├─ 是 → **BroadcastChannel** (API 最简洁)
└─ 否 → 考虑 `window.postMessage` (用于与 iframe/弹窗等特定窗口通信)| 场景描述 | 推荐方案 | 核心理由 | 代码示例思路 |
|---|---|---|---|
| 1. 共享后台连接 (如 WebSocket、SSE) | SharedWorker | 避免每个标签页都建立连接,节省服务器资源。 | 连接逻辑写在 Worker 中,各页面通过 Worker 收发消息。 |
| 2. 多标签页状态同步 (登录状态、主题、购物车数量) | localStorage + storage 事件 | 兼容性最好,数据有持久性,刷新页面不丢失。 | 一个页面 setItem,其他页面监听 storage 事件来更新 UI。 |
| 3. 实时、简单的消息广播 (通知所有页面刷新、播放提示音) | BroadcastChannel | API 极其简洁,性能好,专为此类场景设计。 | new BroadcastChannel('xxx') 然后 postMessage 即可。 |
