【前端技术】标签页通讯localStorage、BroadcastChannel、SharedWorker的技术详解

在这里插入图片描述

😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~
🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志
🎐 个人CSND主页——Micro麦可乐的博客
🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战
🌺《RabbitMQ》专栏主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战
🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解
💕《Jenkins实战》专栏主要介绍Jenkins+Docker的实战教程,让你快速掌握项目CI/CD,是2024年最新的实战教程
🌞《Spring Boot》专栏主要介绍我们日常工作项目中经常应用到的功能以及技巧,代码样例完整
如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~

【前端技术】标签页通讯localStorage、BroadcastChannel、SharedWorker的技术详解

  • 前言
  • 标签页通信的应用场景
    • ❶ 用户登录状态同步
    • ❷ 实时数据更新
    • ❸ 多标签页协同工作
    • ❹ 购物车同步
    • ❺视频、音频播放同步
  • 第一种:localStorage
  • 第二种:BroadcastChannel API
  • 第三种:SharedWorker
  • 结语

前言

随着 Web 应用的复杂化和功能的增加,很多时候我们某些业务功能需要实现标签页间的通讯,基于这种需求下,我们必须要掌握一些标签页通讯的技术,本文博主将和大家分享三种常见的标签页通讯技术: localStorage 事件、 BroadcastChannel APISharedWorker

标签页通信的应用场景

浏览器标签页之间的通讯在实际应用中有很多场景。下面博主举几个常见的例子,展不同的需求和解决方案

❶ 用户登录状态同步

应用场景:用户在一个标签页中登录或注销,其他打开同一应用的标签页需要同步登录状态。

解决方案:使用 localStorage 事件或 BroadcastChannel


❷ 实时数据更新

应用场景:在一个标签页中更新数据,其他标签页需要实时显示更新结果,例如股票行情、实时聊天消息等。

解决方案:使用 BroadcastChannel 实现高效的实时通讯。


❸ 多标签页协同工作

应用场景:用户在多个标签页中打开同一个应用,需要各标签页协同工作。例如,在一个标签页中填写表单,另一个标签页显示表单预览

解决方案:使用 SharedWorker 进行复杂数据和状态共享,或者 BroadcastChannel 进行简单消息传递


❹ 购物车同步

应用场景:用户在一个标签页中添加商品到购物车,其他标签页需要同步购物车内容

解决方案:使用 localStorage 事件或 BroadcastChannel 实现购物车内容的同步


❺视频、音频播放同步

应用场景:用户在多个标签页中同时打开同一个视频,控制一个标签页的视频播放,其他标签页的视频需要同步播放或暂停(可以参考国内的酷狗音乐网站: 播放音乐标签页的效果

解决方案:使用 BroadcastChannel 实现同步控制


以上举例仅仅是标签页通讯应用场景的其中几种,实际上还存在更多场景,博主就不一一展开了

第一种:localStorage

在这里插入图片描述
localStorage 是一种持久化的存储机制,它允许在浏览器中存储键值对。当 localStorage 的数据在一个标签页中被修改时,其他所有打开同一页面的标签页都会接收到一个 storage 事件。这一特性使得我们可以利用 localStorage 实现不同标签页之间的通讯。

localStorage 的基本特点

  • 持久性:数据存储在 localStorage 中,即使浏览器关闭后也会保留
  • 同源策略:同一来源(origin)下的所有页面都可以访问相同的 localStorage 数据
  • 容量限制:大多数浏览器限制在 5MB 左右

代码示例
下面我们通过一个具体的示例,展示如何利用 localStorage 实现标签页之间的通讯

标签页 A:发送消息

<!DOCTYPE html>
<html>
<head><title>标签页 A</title>
</head>
<body><button onclick="sendMessage('这是来自标签页A的消息')">发送消息</button><script>function sendMessage(message) {localStorage.setItem('message', message);}</script>
</body>
</html>

标签页 B:接收消息

<!DOCTYPE html>
<html>
<head><title>标签页 B</title>
</head>
<body><script>window.addEventListener('storage', (event) => {if (event.key === 'message') {console.log('我是标签页B接受到的消息: ', event.newValue);}});</script>
</body>
</html>

localStorage标签页通讯优点

  • 简单易用:实现方法简单,代码量少
  • 浏览器支持广泛:大多数现代浏览器都支持 localStorage

localStorage标签页通讯缺点

  • 同步问题:storage 事件是异步的,不适用于需要实时通讯的场景。
  • 数据存储限制:localStorage 容量有限,一般为 5MB。
  • 安全性:localStorage 中的数据是明文存储的,需要注意敏感数据的存储安全。

第二种:BroadcastChannel API

在这里插入图片描述

BroadcastChannel 是一种用于在同一来源(同一协议、主机名和端口号)下不同浏览器上下文(如标签页iframeWorkerService Worker)之间进行消息广播的 API。它提供了一种简便、可靠的方法来实现跨上下文的实时通讯

BroadcastChannel 的基本概念

  • 广播频道:BroadcastChannel 创建的实例代表一个特定的广播频道,所有监听该频道的上下文都能接收该频道发送的消息
  • 消息广播:通过 postMessage 方法发送消息,所有监听该频道的上下文都会收到消息
  • 消息监听:通过 onmessage 事件处理器接收和处理来自该频道的消息

BroadcastChannel 的特点

  • 实时通讯:能够在不同浏览器上下文之间进行实时消息传递。
  • 简洁易用:API 简单明了,只需少量代码即可实现。
  • 同源策略:确保安全性,只有同源的上下文才能相互通讯。

基本用法

创建频道:在多个上下文中使用相同的频道名称创建 BroadcastChannel 实例

const channel = new BroadcastChannel('my_channel');

发送消息:在任意一个上下文中,通过 postMessage 方法向频道发送消息

channel.postMessage('Hello from one context');

接收消息:在其他上下文中,通过监听 onmessage 事件接收消息

channel.onmessage = (event) => {console.log('Received message:', event.data);
};

代码示例
通过上述基本用法的介绍,我们现在可以用一个代码示例来演示一下

标签页 A 的代码

<!DOCTYPE html>
<html>
<head><title>Page A</title>
</head>
<body><button onclick="sendMessage()">发送消息</button><script>const channel = new BroadcastChannel('my_channel');function sendMessage() {channel.postMessage('这是来自标签页A的消息');//传递对象channel.postMessage({ type: 'update', data: '更新的数据' });}</script>
</body>
</html>

标签页 B 的代码

<!DOCTYPE html>
<html>
<head><title>Page B</title>
</head>
<body><script>const channel = new BroadcastChannel('my_channel');channel.onmessage = (event) => {console.log('标签页B接受消息:', event.data);//接受对象if (event.data.type === 'update') {console.log('标签页B接受update类型消息:', event.data.data);}};</script>
</body>
</html>

BroadcastChannel通讯优点

  • 实时性好:消息几乎是实时传递的,适用于需要即时通讯的场景
  • 使用简单:不需要复杂的设置,易于实现和维护
  • 跨上下文:支持标签页iframeWorker 和 Service Worker 之间的通讯,适用范围广

BroadcastChannel通讯缺点

  • 不持久化:消息不会持久化,页面刷新或关闭后,之前的消息无法再获取
  • 同源限制:只能在同源上下文之间通讯,不同来源无法相互通讯

第三种:SharedWorker

在这里插入图片描述
SharedWorker 是一种允许多个浏览器上下文(如标签页iframe)共享一个 Worker 实例的技术,能够实现跨多个上下文的通讯和数据共享。通过 SharedWorker 我们可以在同一来源(同一协议、主机名和端口号)下的不同浏览器上下文之间进行高效的通讯

SharedWorker 的基本概念

  • SharedWorker 实例:多个上下文共享一个 Worker 实例,所有上下文可以通过这个 Worker 实例进行通讯
  • 连接和通讯:每个上下文通过 port 对象与 SharedWorker 通讯,portMessagePort 的实例
  • 消息传递:通过 postMessage 方法发送消息,通过 onmessage 事件处理器接收消息

SharedWorker 的特点

  • 共享实例:多个上下文共享一个 Worker 实例,节省资源
  • 双向通讯:通过 MessagePort 实现双向通讯
  • 同源策略:确保安全性,只有同源的上下文才能相互通讯

基本用法

创建和连接 SharedWorker:在 JavaScript 文件中定义 SharedWorker 脚本

// sharedWorker.js
self.onconnect = function(event) {const port = event.ports[0];port.onmessage = function(event) {// 处理来自页面的消息console.log('接收来自页面的消息:', event.data);// 可以将消息发送给其他连接的端口port.postMessage('来自SharedWorker的回复');};
};

在 HTML 页面中创建并连接 SharedWorker

// 页面 A 和页面 B 中的代码
const sharedWorker = new SharedWorker('sharedWorker.js');
const port = sharedWorker.port;// 发送消息
port.postMessage('Hello from Page');// 接收消息
port.onmessage = (event) => {console.log('Received from SharedWorker:', event.data);
};

示例代码
编写一个 SharedWorker 脚本 sharedWorker.js

let connections = [];self.onconnect = function(event) {const port = event.ports[0];connections.push(port);port.onmessage = function(event) {console.log('Received from page:', event.data);// 广播消息给所有连接的端口connections.forEach(conn => {if (conn !== port) {conn.postMessage(event.data);}});};port.start();
};

标签页 A 的代码

<!DOCTYPE html>
<html>
<head><title>页面 A</title>
</head>
<body><button onclick="sendMessage()">发送页面A消息</button><script>const sharedWorker = new SharedWorker('sharedWorker.js');const port = sharedWorker.port;port.start();function sendMessage() {port.postMessage('这是来自页面A的消息');}port.onmessage = (event) => {console.log('接收来自SharedWorker的消息:', event.data);};</script>
</body>
</html>

标签页 B 的代码

<!DOCTYPE html>
<html>
<head><title>Page B</title>
</head>
<body><button onclick="sendMessage()">发送页面B消息</button><script>const sharedWorker = new SharedWorker('sharedWorker.js');const port = sharedWorker.port;port.start();function sendMessage() {port.postMessage('这是来自页面B的消息');}port.onmessage = (event) => {console.log('接收来自SharedWorker的消息:', event.data);};</script>
</body>
</html>

SharedWorker优点

  • 高效资源利用:共享一个 Worker 实例,减少内存和 CPU 占用
  • 灵活的消息处理:可以在 Worker 中集中处理和分发消息,适用于复杂的通讯需求
  • 持久连接:连接建立后可以长时间保持,不需要频繁建立和销毁连接

SharedWorker缺点

  • 实现复杂:相比 BroadcastChannel,实现起来稍微复杂一些
  • 同源限制:只能在同源上下文之间通讯,不同来源无法相互通讯
  • 浏览器支持:部分旧版浏览器可能不支持 SharedWorker

结语

到这里博主已经详细介绍了三种常见的浏览器标签页通讯方式,包括 localStorage 事件、BroadcastChannel APISharedWorker,这些技术各有优劣,小伙伴可以根据实际需求选择合适的解决方案,以实现高效的标签页间通讯。

文中的代码样例大家可以直接复制测试运行效果,如果本文对您有所帮助,希望 一键三连 给博主一点点鼓励,如果您有任何疑问或建议,请随时留言讨论!


在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/857354.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis大key有什么危害?如何排查和处理?

什么是 bigkey&#xff1f; 简单来说&#xff0c;如果一个 key 对应的 value 所占用的内存比较大&#xff0c;那这个 key 就可以看作是 bigkey。具体多大才算大呢&#xff1f;有一个不是特别精确的参考标准&#xff1a; String 类型的 value 超过 1MB 复合类型&#xff08;Li…

一个漂亮的网站收藏函数

<!DOCTYPE html> <html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>网站收藏</title><style>body …

云手机群控功能讲解

接触云手机之前&#xff0c;很多企业或者个人卖家都对群控有浓厚的兴趣&#xff0c;云手机群控具体是什么呢&#xff1f;云手机群控&#xff0c;顾名思义&#xff0c;是指能够同时对多台云手机进行集中控制和管理的功能。打破了传统单台手机操作的限制&#xff0c;实现了规模化…

高精度乘法的实现

这是C算法基础-基础算法专栏的第九篇文章&#xff0c;专栏详情请见此处。 引入 上次我们学习了高精度加法的实现&#xff0c;这次我们要学习高精度减法的实现。 高精度乘法与高精度加法的定义、前置过程都是大致相同的&#xff0c;如果想了解具体内容&#xff0c;可以移步至我的…

查看LabVIEW及各个模块和驱动的版本号

要方便地查看当前计算机上安装的LabVIEW版本以及各个模块和驱动的版本号&#xff0c;可以使用以下几种方法&#xff1a; 1. 使用NI MAX (Measurement & Automation Explorer) NI MAX 是一个强大的工具&#xff0c;可以帮助你管理National Instruments硬件、软件和驱动程序…

Docker(三)-Docker常用命令

1.run run命令执行流程:2.帮助启动类命令 2.1 启动docker systemctl start docker2.2 停止docker systemctl stop docker2.3 重启docker systemctl restart docker2.4查看docker状态 systemctl status docker2.5开机启动 systemctl enable docker2.6查看docker概要信息 …

VB.net实战(VSTO):VSTOwpf体验框架打包教程

如果是考虑到Wps用户较多&#xff0c;就不建议采用侧边栏的形式 只是个体验框架&#xff0c;界面未作美化&#xff0c;office的用户可以用任意一种窗体&#xff0c;喜欢那个界面就写那个界面&#xff0c;wps的侧边栏只能弹出一部分&#xff0c;每次需要的手动拖动。 打包了案例…

Java——IO流(一)-(6/8):字节流-FileInputStream 每次读取多个字节(示例演示)、一次读取完全部字节(方式一、方式二,注意事项)

目录 文件字节输入流&#xff1a;每次读取多个字节 实例演示 注意事项 文件字节输入流&#xff1a;一次读取完全部字节 方式一 方式二 注意事项 文件字节输入流&#xff1a;每次读取多个字节 用到之前介绍过的常用方法&#xff1a; 实例演示 需求&#xff1a;用每次读取…

诸茅的黄昏

内容提要 白酒大陆的坍塌终于到达茅台的地盘&#xff0c;一切发生得太快了。突然间&#xff0c;深厚的护城河消失了&#xff0c;医药茅、眼科茅、牙科茅、疫苗茅、酱油茅都挣扎于内需的泥沼中。旧茅衰退&#xff0c;新茅生长&#xff0c;在下行周期&#xff0c;内需仍有结构性…

C#修改 EXE 文件图标和 winForm 窗口图标

修改 EXE 文件图标 1.准备好图片&#xff0c;转换为 Icon 图片&#xff1b; 2.右键工程&#xff0c;选择属性&#xff1b; 3.选择 Icon 图标即可&#xff1b; 4.重新生成可执行文件&#xff0c;查看。 修改 winForm 窗口图标 1.选中 winForm &#xff0c;查看属性&#x…

「51媒体」时尚类媒体邀约宣发资源

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 时尚类媒体邀约宣发资源可以多样化且针对性地满足品牌或活动的推广需求。以下是一些主要的资源及其特点&#xff1a; 时尚杂志&#xff1a;国内外知名时尚杂志&#xff0c;如《Vogue》、…

手机怎么自动切换ip地址

在数字化时代&#xff0c;网络IP地址不仅是设备在网络世界的标识&#xff0c;也是确保用户网络安全和数据隐私的关键因素。对于手机用户来说&#xff0c;在某些情境下可能需要自动切换IP地址&#xff0c;本文将为您介绍手机怎么自动切换IP地址。 随着网络技术的发展&#xff0c…

一些使用注意(XPTable控件使用说明十)

当XPTABLE放到线程中&#xff0c;列数据很多&#xff0c;不出现滚动条的解决代码&#xff1a; /// 这里神奇的代码&#xff0c;解决线程中XPTABLE 不出滚动条问题 , 执行UI相关的操作this.Invoke(new Action(() >{ // 列头&#xff0c;一行空的&#xff0c;这里列头设置…

蓝桥杯 经典算法题 求解完全背包问题

题目&#xff1a; 题解&#xff1a; 和01背包基本完全一样。小局部最优的策略也是一样&#xff1a;是否选当前局部的最后一项。唯一的不同点在于物品是无线的导致在表示选择当前物品的状态写法发生了改变&#xff1a;由dp[i-1][j-w[i]]变为了dp[i][j-w[i]]因为这样能够表示最后…

读AI新生:破解人机共存密码笔记08超级智能

1. 发现动作 1.1. 时间跨度长的智能行为&#xff0c;需要具备在多个抽象层次上分层规划和管理活动的能力&#xff0c;从攻读博士学位&#xff08;可能涉及1万亿个动作&#xff09;&#xff0c;到给一根手指发送一个运动控制指令&#xff0c;从而键入求职信的字符&#xff0c;无…

用户态协议栈04-定时arp-table的实现

之前有写过arp reply的实现&#xff0c;其中有写道&#xff0c;我们的系统内核中会维护一张ARP表&#xff0c;可以通过终端arp -a查看&#xff1a; 其中的dynamic和static是动态arp的类型&#xff0c;之前的udp实验就是添加了一条静态arp达到了发送的目的。在我们需要发送一个数…

AI播客下载:Machine Learning Street Talk(AI机器学习)

该频道由 Tim Scarfe 博士、Yannic Kilcher 博士和 Keith Duggar 博士管理。 他们做了出色的工作&#xff0c;对每个节目进行了彻底的研究&#xff0c;并与机器学习行业中一些受过最高教育、最全面的嘉宾进行了双向对话。 每一集都会教授一些新内容&#xff0c;并且提供未经过滤…

C++入门超详细解释

C入门 文章目录 C入门框架命名空间 namespace &#xff08;不常用&#xff09;命名空间的使用方式&#xff08;三种&#xff09;using namespace std;\<iostream>coutendlcincout的使用命名冲突缺省参数&#xff08;省钱的省&#xff09;缺省参数分类全缺省参数半缺省参数…

论文浅读之Mamba: Linear-Time Sequence Modeling with Selective State Spaces

介绍 这篇论文提出了一种新型的"选择性状态空间模型"(Selective State Space Model, S6)来解决之前结构化状态空间模型(SSM)在离散且信息密集的数据&#xff08;如文本&#xff09;上效果较差的问题。 Mamba 在语言处理、基因组学和音频分析等领域的应用中表现出色。…

安卓设备优雅的命令 adb 以及 优秀的控制 scrcpy

一、背景 如果有多台安卓设备&#xff0c;并为这些设备安装软件&#xff0c;一个个使用u盘再加上鼠标操作虽然可以做到&#xff0c;但是大概率比较麻烦。试想下&#xff0c;如果坐在电脑旁边&#xff0c;就能鼠标在电脑上点点就能解决问题&#xff0c;是多么优雅的一件事情。 …