# 1 跨标签页通讯
⚡ 30 秒速记
- 同源首选
BroadcastChannel:同频道名的同源页面都能收到,发送方自己收不到 storage事件兼容最广,两个坑:只通知其他页面、写入同值不触发(带时间戳)SharedWorker适合多个标签页共用一条WebSocket;Safari 16才重新支持,上线前查兼容- 有父子关系的窗口用
postMessage,接收方必须校验event.origin - 跨浏览器、跨设备只能走服务端
WebSocket/SSE;cookie+setInterval轮询是过时写法
同一个浏览器里的同源标签页,我首选 BroadcastChannel,跨设备才上服务端推送。 BroadcastChannel 就像一个同源页面共享的对讲频道,一个页面 postMessage,同频道的其他页面 onmessage 都能收到,最典型的用法是一处退出、所有标签页一起登出。要兼容很老的浏览器就用 storage 事件兜底,但它本质是借存储的副作用通信,同值不触发,所以消息里要带时间戳。如果目标是多个页面共享一条长连接,那就是 SharedWorker 的活。
跨标签页通信要先分两类场景:同源的纯浏览器通信,和需要服务端中转的跨设备同步。
① BroadcastChannel(同源首选)
const channel = new BroadcastChannel('auth')
channel.postMessage({ type: 'logout' }) // A 标签页发
channel.onmessage = (e) => { ... } // B 标签页收(发送方自己不触发)
window.addEventListener('pagehide', () => channel.close())
语义最直接:同一个频道名的所有同源上下文都能收到。
② storage 事件(兼容性最广)
localStorage.setItem('msg', JSON.stringify({ type: 'logout', t: Date.now() }))
window.addEventListener('storage', (e) => { if (e.key === 'msg') { /* ... */ } })