解决前端多标签页通信: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 非常适用于同源页面在多窗口、多标签页场景下的数据或状态同步,做到保持相同页面在同一时刻下数据的一致性。

相关推荐
墨鸦_Cormorant3 小时前
Vue 概述以及基本使用
前端·javascript·vue.js
JarvanMo3 小时前
10 个能帮你节省大量开发时间的低估 Flutter 组件
前端
去伪存真3 小时前
公司前端项目ESLint规则集统一化
前端
鹏多多3 小时前
使用imaskjs实现js表单输入卡号/日期/货币等掩码的教程
前端·javascript·vue.js
w2vmany3 小时前
postmessage xss初步学习
前端·学习·xss
小张成长计划..4 小时前
前端6:CSS3 2D转换,CSS3动画,CSS3 3D转换
前端·3d·css3
IT_陈寒4 小时前
Vue3性能优化实战:这7个技巧让我的应用加载速度提升50%!
前端·人工智能·后端
西西学代码4 小时前
Flutter---音效模式选择器
前端·html
TLucas4 小时前
Layui连线题编辑器组件(ConnectQuestion)
前端·编辑器·layui