瀏覽器悄悄上線了這個(gè) API,大大簡化了跨瀏覽器標(biāo)簽頁通信
過去,最常見的就是利用 localStorage 的 onstorage 事件監(jiān)聽來處理跨瀏覽器標(biāo)簽頁通信,但其本職是存儲(chǔ),通信只是其副作用,且 API 不夠直觀。
現(xiàn)代瀏覽器已經(jīng)為我們提供了一個(gè)專門為此場景設(shè)計(jì)的、更優(yōu)雅、更高效的解決方案。

什么是 BroadcastChannel?
BroadcastChannel API 允許來自同源的瀏覽器不同上下文(如標(biāo)簽頁、窗口、iframe)之間進(jìn)行通信。
其核心特點(diǎn)是:同源限制、發(fā)布/訂閱模式且角色可以互換、基于消息事件對高效通信、支持復(fù)雜數(shù)據(jù),無需手動(dòng)序列化。
它的 API 非常簡潔,主要包含創(chuàng)建、發(fā)送、接收和關(guān)閉四個(gè)步驟。
1. 創(chuàng)建或加入一個(gè)頻道
要進(jìn)行通信,首先需要?jiǎng)?chuàng)建一個(gè) BroadcastChannel 實(shí)例,并給它指定一個(gè)唯一的頻道名稱。所有希望通信的頁面都必須使用相同的頻道名稱。
// 創(chuàng)建一個(gè)名為 'user_status_channel' 的頻道
const channel = new BroadcastChannel('user_status_channel');如果名為 user_status_channel 的頻道已存在,這行代碼會(huì)加入該頻道;如果不存在,則會(huì)創(chuàng)建它。
2. 發(fā)送消息
創(chuàng)建實(shí)例后,使用 postMessage() 方法向頻道廣播消息。所有監(jiān)聽該頻道的其他標(biāo)簽頁都會(huì)收到此消息。

postMessage() 的強(qiáng)大之處在于它可以發(fā)送各種復(fù)雜的數(shù)據(jù)結(jié)構(gòu),包括對象、數(shù)組、Map、Set、File 對象等,瀏覽器會(huì)自動(dòng)處理序列化和反序列化。
3. 接收消息
通過監(jiān)聽 message 事件來接收廣播。事件對象 event 中包含了我們最關(guān)心的 data 屬性,也就是發(fā)送方傳遞的消息。
channel.onmessage = (event) => {
 console.log('收到消息:', event.data);
 // 根據(jù)消息內(nèi)容執(zhí)行相應(yīng)操作
 if (event.data && event.data.type === 'login') {
    updateUIForLogin(event.data.user);
  } else if (event.data && event.data.type === 'logout') {
    updateUIForLogout();
  }
};
// 也可以使用 addEventListener
// channel.addEventListener('message', (event) => { ... });4. 關(guān)閉頻道
當(dāng)頁面不再需要接收或發(fā)送消息時(shí)(例如,在組件卸載或頁面關(guān)閉時(shí)),應(yīng)該調(diào)用 close() 方法來關(guān)閉頻道,以釋放資源。
// 當(dāng)組件銷毀或頁面關(guān)閉時(shí)
window.onunload = () => {
  channel.close();
};
// 在 React 或 Vue 等框架中,可以在組件的卸載生命周期函數(shù)中調(diào)用
// useEffect(() => {
//   return () => channel.close();
// }, []);BroadcastChannel API 是實(shí)現(xiàn)同源跨標(biāo)簽頁通信的現(xiàn)代化標(biāo)準(zhǔn)方案,具有簡潔的 API、強(qiáng)大的功能和優(yōu)秀的性能,完美地解決了 localStorage hack 方案的各種痛點(diǎn)。
至于兼容性,只要不用 IE 就行。















 
 
 



 
 
 
 