解决前端多标签页通信:BroadcastChannel

大家好,我是 CC,在这里欢迎大家的到来~

背景

日常使用一些网站过程中,会发现当打开一个网站多个标签页时,当在其中一个标签页页面退出登录时,在其他标签页中还可以继续操作,这里就存在一个状态没有实时统一的问题 ;其后当操作发送请求时根据后端的登录校验情况会跳转到登录页,而这个操作滞后了。比如常用的 AI 网站 DeepSeek

那如何在多标签页下进行状态的同步呢,这时候就要请出今天的"主人公"- BroadcastChannel

来浅浅实践一下

使用起来很简单。

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>BroadcastChannel</title>
</head>
<body>
  <h1>BroadcastChannel</h1>
  <script>
    const channel = new BroadcastChannel('my-channel');
    channel.postMessage('hello world');

    channel.onmessage = (event) => {
      console.log(event.data);
    }
  </script>
</body>
</html>

效果

在两个浏览器窗口中分别打开页面,当一个页面刷新后发送消息时,之前打开的相同页面收到了消息内容,但是当前页面没有收到消息内容。

注意

  • 适用于同源不同浏览器窗口、浏览器标签页、iframe之间互相通信
  • 通过 message 事件进行广播
  • 在监听该 channel 的所有 BroadcastChannel 对象上触发,但是不包含发送消息的对象

应用

举两个业务中会用到的例子:

同步登录状态

当多个页面处于未登录状态时,在其中一个页面上登录成功后,所有的页面都会收到消息,更新登录状态及页面路由。

js 复制代码
// 登录状态管理
const authChannel = new BroadcastChannel('auth');

// 登录成功后
function handleLogin(user) {
  localStorage.setItem('token', user.token);
  authChannel.postMessage({
    type: 'LOGIN_SUCCESS',
    user: user
  });
}

// 监听登录状态
authChannel.onmessage = (event) => {
  switch (event.data.type) {
    case 'LOGIN_SUCCESS':
      updateUserInfo(event.data.user);
      break;
    case 'LOGOUT':
      clearUserData();
      redirectToLogin();
      break;
  }
};

同步页面设置

在多个 AI 对话页面场景下,在其中一个页面上个更改了 LLM 对话参数 Temperature 时,其余页面中相应参数也会更改,避免后知后觉**。**

js 复制代码
// 应用配置同步
const configChannel = new BroadcastChannel('app-config');

// 管理员更新配置
function updateAppSettings(settings) {
  configChannel.postMessage({
    type: 'SETTINGS_UPDATED',
    settings: settings
  });
}

// 所有页面应用新配置
configChannel.onmessage = (event) => {
  if (event.data.type === 'SETTINGS_UPDATED') {
    applyNewSettings(event.data.settings);
    showNotification('配置已更新');
  }
};

同步业务数据

在多个页面对比商品时,在其中一个页面中加购商品后其余页面也会更新购物车列表,保证数据的一致性。

js 复制代码
// 购物车同步
const cartChannel = new BroadcastChannel('cart');

// 添加商品时通知其他标签页
function addToCart(product) {
  const cart = getCartFromStorage();
  cart.push(product);
  localStorage.setItem('cart', JSON.stringify(cart));
  
  cartChannel.postMessage({
    type: 'CART_UPDATE',
    cart: cart
  });
}

// 监听购物车变化
cartChannel.onmessage = (event) => {
  if (event.data.type === 'CART_UPDATE') {
    updateCartUI(event.data.cart);
  }
};

对比其他方案

通信方式 适用场景 特点
BroadcastChannel 同源标签页通信 简单易用,不支持跨域
LocalStorage 事件 简单数据同步 兼容性好,数据大小限制
SharedWorker 复杂数据共享 功能强大,实现复杂
Window.postMessage 跨域通信 需要引用目标窗口

总结

BroadcastChannel 非常适用于同源页面在多窗口、多标签页场景下的数据或状态同步,做到保持相同页面在同一时刻下数据的一致性。

相关推荐
吃杠碰小鸡10 分钟前
高中数学-数列-导数证明
前端·数学·算法
kingwebo'sZone16 分钟前
C#使用Aspose.Words把 word转成图片
前端·c#·word
xjt_090136 分钟前
基于 Vue 3 构建企业级 Web Components 组件库
前端·javascript·vue.js
我是伪码农1 小时前
Vue 2.3
前端·javascript·vue.js
夜郎king1 小时前
HTML5 SVG 实现日出日落动画与实时天气可视化
前端·html5·svg 日出日落
辰风沐阳1 小时前
JavaScript 的宏任务和微任务
javascript
夏幻灵2 小时前
HTML5里最常用的十大标签
前端·html·html5
冰暮流星2 小时前
javascript之二重循环练习
开发语言·javascript·数据库
Mr Xu_2 小时前
Vue 3 中 watch 的使用详解:监听响应式数据变化的利器
前端·javascript·vue.js
未来龙皇小蓝2 小时前
RBAC前端架构-01:项目初始化
前端·架构