前端跨标签页通信方案(上)

前情

平时开发很少有接触到有什么需求需要实现跨标签页通信,但最近因为一些变故,不得不重新开始找工作了,其中就有面试官问到一道题,跨标签页怎么实现数据通信,我当时只答出二种,面试完后特意重新查资料,因此有些文章

localStorage / sessionStorage

利用localStorage的存储事件实现通信,当一个标签页修改localStorage时,其他同源标签页会触发storage事件

关键代码如下:

标签页1

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>page0-localStorage</title>
</head>
<body>
  <button id="setCacheBtn">设置本地缓存</button>
  <script>
    document.getElementById('setCacheBtn').addEventListener('click', () => {
      localStorage.setItem('message', JSON.stringify({
        type: 'greeting',
        // 这里为了保证通信每次生效,每次都设置不同的值
        content: 'Hello from page0.html' + Date.now()
      }));
    });
  </script>
</body>
</html>

标签页2

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>page1-localStorage</title>
</head>
<body>
  <script>
    window.addEventListener('storage', (e) => {
      if (e.key === 'message') {
        const data = JSON.parse(e.newValue);
        console.log('Received:page1.html', data);
      }
    });
  </script>
</body>
</html>

动图演示:

提醒:

  • 同源标签才有效
  • 设置不同的本地存储值才有效,如果设置的是同一个缓存值是不会生效的
  • 兼容性非常nice,可以大胆使用了,国内一些浏览器从can i use查不到,但兼容性是没啥问题的
  • sessionStorage仅在同一标签页的不同 iframe 间有效,不适用于不同标签页

BroadcastChannel

专门用于同源标签页通信的 API,创建一个频道后,所有加入该频道的页面都能收到消息

关键代码如下:

标签页1

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>BroadcastChannel0</title>
</head>
<body>
  <h1>BroadcastChannel0</h1>
  <button id="communication">BroadcastChannel0.html 发送消息</button>
  <script>
    // 所有页面都创建相同名称的频道
    const channel = new BroadcastChannel('my_channel');

    // 发送消息
    document.getElementById('communication').addEventListener('click', () => {
      channel.postMessage({ type: 'update', data: 'new content from BroadcastChannel0.html' });
    });
  </script>
</body>
</html>

标签页2

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>BroadcastChannel1</title>
</head>
<body>
  <h1>BroadcastChannel1</h1>
  <script>
    // 所有页面都创建相同名称的频道
    const channel = new BroadcastChannel('my_channel');

    // 接收消息
    channel.onmessage = (e) => {
      console.log('Received:BroadcastChannel1.html', e.data);
    };
  </script>
</body>
</html>

演示动图如下:

提醒:

  • 要通信的标签记得都初始化BroadcastChannel,一定记得使用相同的名称
  • 查询来看除IE外可以大但使用了

小结

这二种是我面试的时候答出来的,第二种我只是模糊记得跟面试官模棱二可的说了说,面试馆给了正面的回应,呵呵......,此文暂时写这么多,下篇继续探索其它方式......

相关推荐
顺颂时绥_16 分钟前
前端大图片压缩与安卓/苹果设备矫正实践
前端
Allshadow7 分钟前
Nest.js - 目录结构
javascript·nestjs
Csvn9 分钟前
JSON.parse 大数精度丢失:一个让前后端互相甩锅的 Bug
前端
张元清15 分钟前
React useCookie Hook:把 Cookie 变成响应式状态(2026)
javascript·react.js
Helen_cai28 分钟前
OpenHarmony 项目统一全局样式、尺寸、色彩主题封装 ThemeUtil(API23)
开发语言·前端·javascript·华为·harmonyos
郑州光合科技余经理29 分钟前
家政O2O平台解析:从0搭建上门预约小程序解决方案
android·java·开发语言·前端·小程序·架构·php
小徐_233340 分钟前
AI 写 wot-ui 总在猜 API?我们把 Skills、MCP 和 CLI 都配好了
前端·uni-app·ai编程
winfredzhang1 小时前
用 wxPython + ECharts + 阿里矢量地图,做一个可离线兜底的上海雨量看板
前端·javascript·echarts
索西引擎1 小时前
【React】Immer.js 在现代 Redux 生态中的角色:不可变性保障的工程化实现与开发体验优化
前端·javascript·react.js
kisshyshy1 小时前
《川剧变脸 × React 状态管理?我在浏览器里跑了个端侧大模型》
前端·react.js·架构