【前端技术】标签页通讯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.mfbz.cn/a/735006.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL之复制(十二)

复制 复制的问题和解决方案 未定义的服务器ID 如果没有在my.cnf里面定义服务器ID,可以通过CHANGE MASTER TO 来设置备库&#xff0c;但却无法启动复制。 mysql>START SLAVE; ERROR 1200(HY000):The server is not configured as slave;fix in config file or with CHANG…

实验13 简单拓扑BGP配置

实验13 简单拓扑BGP配置 一、 原理描述二、 实验目的三、 实验内容四、 实验配置五、 实验步骤 一、 原理描述 BGP&#xff08;Border Gateway Protocol&#xff0c;边界网关协议&#xff09;是一种用于自治系统间的动态路由协议&#xff0c;用于在自治系统&#xff08;AS&…

汇聚荣做拼多多运营怎么样?

汇聚荣做拼多多运营怎么样?在电商行业竞争日益激烈的今天&#xff0c;拼多多作为一家迅速崛起的电商平台&#xff0c;吸引了众多商家入驻。对于汇聚荣这样的企业而言&#xff0c;选择在拼多多上进行商品销售和品牌推广&#xff0c;无疑需要一套高效的运营策略。那么&#xff0…

技术师增强版,系统级别的工具!【不能用】

数据安全是每位计算机用户都关心的重要问题。在日常使用中&#xff0c;我们经常面临文件丢失、系统崩溃或病毒感染等风险。为了解决这些问题&#xff0c;我们需要可靠且高效的数据备份与恢复工具。本文将介绍一款优秀的备份软件&#xff1a;傲梅轻松备份技术师增强版&#xff0…

【MySQL数据库】:MySQL视图特性

目录 视图的概念 基本使用 准备测试表 创建视图 修改视图影响基表 修改基表影响视图 删除视图 视图规则和限制 视图的概念 视图是一个虚拟表&#xff0c;其内容由查询定义&#xff0c;同真实的表一样&#xff0c;视图包含一系列带有名称的列和行数据。视图中的数据…

地下管线管网三维建模系统MagicPipe3D

地下管网是保障城市运行的基础设施和“生命线”。随着实景三维中国建设的推进&#xff0c;构建地下管网三维模型与地上融合的数字孪生场景&#xff0c;对于提升智慧城市管理至关重要&#xff01;针对现有三维管线建模数据差异大、建模交互弱、模型效果差、缺乏语义信息等缺陷&a…

多功能投票系统(ThinkPHP+FastAdmin+Uniapp)

让决策更高效&#xff0c;更民主&#x1f31f; ​基于ThinkPHPFastAdminUniapp开发的多功能系统&#xff0c;支持图文投票、自定义选手报名内容、自定义主题色、礼物功能(高级授权)、弹幕功能(高级授权)、会员发布、支持数据库私有化部署&#xff0c;Uniapp提供全部无加密源码…

Android MVP模式 入门

View&#xff1a;对应于布局文件 Model&#xff1a;业务逻辑和实体模型 Controllor&#xff1a;对应于Activity 看起来的确像那么回事&#xff0c;但是细细的想想这个View对应于布局文件&#xff0c;其实能做的事情特别少&#xff0c;实际上关于该布局文件中的数据绑定的操…

高通安卓12-安卓系统定制2

将开机动画打包到system.img里面 在目录device->qcom下面 有lito和qssi两个文件夹 现在通过QSSI的方式创建开机动画&#xff0c;LITO方式是一样的 首先加入自己的开机动画&#xff0c;制作过程看前面的部分 打开qssi.mk文件&#xff0c;在文件的最后加入内容 PRODUCT_CO…

【SSM】医疗健康平台-管理端-检查组管理

技能目标 掌握新增检查组功能的实现 掌握查询检查组功能的实现 掌握编辑检查组功能的实现 掌握删除检查组功能的实现 体检的检查项种类繁多&#xff0c;为了方便管理和快速筛选出类别相同的检查项&#xff0c;医疗健康将类别相同的检查项放到同一个检查组中进行管理&#…

ANR灵魂拷问:四大组件中的onCreate-onReceive方法中Thread-sleep(),会产生几个ANR-

findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() { Override public void onClick(View v) { sleepTest(); } }); sleepTest方法详情 public void sleepTest(){ new Handler().postDelayed(new Runnable() { Override public void run() { Button but…

<Rust><iced>在iced中显示gif动态图片的一种方法

前言 本文是在rust的GUI库iced中在窗口显示动态图片GIF格式图片的一种方法。 环境配置 系统&#xff1a;window 平台&#xff1a;visual studio code 语言&#xff1a;rust 库&#xff1a;iced、image 概述 在iced中&#xff0c;提供了image部件&#xff0c;从理论上说&…

软考 系统架构设计师系列知识点之杂项集萃(44)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之杂项集萃&#xff08;43&#xff09; 第71题 设有员工实体Employee&#xff08;员工号&#xff0c;姓名&#xff0c;性别&#xff0c;年龄&#xff0c;电话&#xff0c;家庭住址&#xff0c;家庭成员&#xff0c;关系…

自动驾驶⻋辆环境感知:多传感器融合

目录 一、多传感器融合技术概述 二、基于传统方法的多传感器融合 三、基于深度学习的视觉和LiDAR的目标级融合 四、基于深度学习的视觉和LiDAR数据的前融合方法 概念介绍 同步和配准 时间同步 标定 摄像机内参标定&#xff08;使用OpenCV&#xff09; 摄像机与LiDAR外…

【FreeRTOS】任务状态改进播放控制

这里写目录标题 1 任务状态1.1 阻塞状态(Blocked)1.2 暂停状态(Suspended)1.3 就绪状态(Ready)1.4 完整的状态转换图 2 举个例子3 编写代码 参考《FreeRTOS入门与工程实践(基于DshanMCU-103).pdf》 本节课实现音乐任务的创建&#xff0c;音乐播放的暂停与继续播放&#xff0c;删…

java泛型学习

没有java泛型会存在的问题 假设我们有一个方法&#xff0c;希望通过传递不同类型的参数&#xff0c;输出不同类型的对象值。正常情况下我们可能会写不同的方法来实现&#xff0c;但是这样会导致类不断增加&#xff0c;并且类方法很相似&#xff0c;不能够复用。进而导致类爆炸…

C#实现音乐在线播放和下载——Windows程序设计作业3

1. 作业内容 编写一个C#程序&#xff0c;在作业二实现的本地播放功能的基础上&#xff0c;新增在线播放和在线下载功能&#xff0c;作业二博客地址&#xff1a;C#实现简单音乐文件解析播放——Windows程序设计作业2 2. 架构选择 考虑到需求中的界面友好和跨版本兼容性&#xf…

网站监控定时计划任务

网站监控是一种保护网站安全和稳定性的重要手段&#xff0c;而定时计划任务则是网站监控的一种常见方法。通过设置定时计划任务&#xff0c;可以定期对网站进行监测和检测&#xff0c;及时发现并解决潜在的问题&#xff0c;从而保障网站的正常运行。 首先&#xff0c;网站监控定…

AI播客下载:Eye on AI(AI深度洞察)

"Eye on A.I." 是一档双周播客节目&#xff0c;由长期担任《纽约时报》记者的 Craig S. Smith 主持。在每一集中&#xff0c;Craig 都会与在人工智能领域产生影响的人们交谈。该播客的目的是将渐进的进步置于更广阔的背景中&#xff0c;并考虑发展中的技术的全球影响…

MySQL的自增 ID 用完了,怎么办?

MySQL 自增 ID 一般用的数据类型是 INT 或 BIGINT&#xff0c;正常情况下这两种类型可以满足大多数应用的需求。 当然也有不正常的情况&#xff0c;当达到其最大值时&#xff0c;尝试插入新的记录会导致错误&#xff0c;错误信息类似于&#xff1a; ERROR 167 (22003): Out o…