浏览器跨标签页通信

176 阅读1分钟

普通网页开发,浏览器标签之间如何进行通信?

1.BroadCast Channel
// 标签页加入同一个"频道"
const channel = new BroadcastChannel('channel');
// 标签1发送消息
channel.postMessage({ action: 'test', item: '测试' });
// 标签2接收消息
channel.onmessage = (event) => {
  console.log('消息:', event.data);
};
2.Service Worker
// service-worker.js
self.addEventListener('message', (event) => {
  self.clients.matchAll().then(clients => {
    clients.forEach(client => client.postMessage(event.data));
  });
});
// 标签页
navigator.serviceWorker.onmessage = (event) => {
  console.log('消息:', event.data);
};
// 发送消息
navigator.serviceWorker.controller.postMessage('测试!');
3.LocalStorage
// 标签1
localStorage.setItem('message', '测试!');
// 标签2
window.addEventListener('storage', (event) => {
  if (event.key === 'message') {
    console.log('消息:', event.newValue);
  }
});
4.Shared Worker
// shared-worker.js
const ports = []; // 所有标签页
onconnect = (e) => {
  const port = e.ports[0];
  ports.push(port);
  port.onmessage = (event) => {
    ports.forEach(p => p !== port && p.postMessage(event.data));
  };
};
// 标签页
const worker = new SharedWorker('shared-worker.js');
worker.port.onmessage = (event) => {
  console.log('消息:', event.data);
};
worker.port.postMessage('测试!');
5.IndexedD
// IndexedDB轮询
setInterval(() => {
  db.get('message').then(val => {
    if (val !== lastMessage) {
      console.log('消息:', val);
      lastMessage = val;
    }
  });
}, 1000);
6.Cookie
// Cookie轮询
setInterval(() => {
  const msg = getCookie('message');
  if (msg !== lastMsg) {
    console.log('消息:', msg);
    lastMsg = msg;
  }
}, 1000);
7.window.open
// 父窗口
const child = window.open('child.html');
child.postMessage('测试1', 'url');
// 子窗口
window.opener.postMessage('测试2', 'url');
// 监听
window.addEventListener('message', (event) => {
  if (event.origin !== 'url') return;
  console.log('消息:', event.data);
});
8.WebSocket
// 所有标签页连接同一个WebSocket
const socket = new WebSocket('wss://example.com/chat');
socket.onmessage = (event) => {
  console.log('消息:', event.data);
};
// 发送消息
socket.send('标签1测试');
使用建议
  1. BroadcastChannel(代码简单)
  2. Service Worker(离线功能)
  3. SharedWorker(大量数据)
  4. localStorage(兼容IE)

仅做记录,具体使用另行搜索实例参考。