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

本文主要是介绍【前端技术】标签页通讯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,这些技术各有优劣,小伙伴可以根据实际需求选择合适的解决方案,以实现高效的标签页间通讯。

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


在这里插入图片描述

这篇关于【前端技术】标签页通讯localStorage、BroadcastChannel、SharedWorker的技术详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1084017

相关文章

Java读取InfluxDB数据库的方法详解

《Java读取InfluxDB数据库的方法详解》本文介绍基于Java语言,读取InfluxDB数据库的方法,包括读取InfluxDB的所有数据库,以及指定数据库中的measurement、field、... 首先,创建一个Java项目,用于撰写代码。接下来,配置所需要的依赖;这里我们就选择可用于与Infl

SpringBoot生成和操作PDF的代码详解

《SpringBoot生成和操作PDF的代码详解》本文主要介绍了在SpringBoot项目下,通过代码和操作步骤,详细的介绍了如何操作PDF,希望可以帮助到准备通过JAVA操作PDF的你,项目框架用的... 目录本文简介PDF文件简介代码实现PDF操作基于PDF模板生成,并下载完全基于代码生成,并保存合并P

Linux中Curl参数详解实践应用

《Linux中Curl参数详解实践应用》在现代网络开发和运维工作中,curl命令是一个不可或缺的工具,它是一个利用URL语法在命令行下工作的文件传输工具,支持多种协议,如HTTP、HTTPS、FTP等... 目录引言一、基础请求参数1. -X 或 --request2. -d 或 --data3. -H 或

Oracle的to_date()函数详解

《Oracle的to_date()函数详解》Oracle的to_date()函数用于日期格式转换,需要注意Oracle中不区分大小写的MM和mm格式代码,应使用mi代替分钟,此外,Oracle还支持毫... 目录oracle的to_date()函数一.在使用Oracle的to_date函数来做日期转换二.日

Java实现任务管理器性能网络监控数据的方法详解

《Java实现任务管理器性能网络监控数据的方法详解》在现代操作系统中,任务管理器是一个非常重要的工具,用于监控和管理计算机的运行状态,包括CPU使用率、内存占用等,对于开发者和系统管理员来说,了解这些... 目录引言一、背景知识二、准备工作1. Maven依赖2. Gradle依赖三、代码实现四、代码详解五

Mysql 中的多表连接和连接类型详解

《Mysql中的多表连接和连接类型详解》这篇文章详细介绍了MySQL中的多表连接及其各种类型,包括内连接、左连接、右连接、全外连接、自连接和交叉连接,通过这些连接方式,可以将分散在不同表中的相关数据... 目录什么是多表连接?1. 内连接(INNER JOIN)2. 左连接(LEFT JOIN 或 LEFT

Java中switch-case结构的使用方法举例详解

《Java中switch-case结构的使用方法举例详解》:本文主要介绍Java中switch-case结构使用的相关资料,switch-case结构是Java中处理多个分支条件的一种有效方式,它... 目录前言一、switch-case结构的基本语法二、使用示例三、注意事项四、总结前言对于Java初学者

Linux内核之内核裁剪详解

《Linux内核之内核裁剪详解》Linux内核裁剪是通过移除不必要的功能和模块,调整配置参数来优化内核,以满足特定需求,裁剪的方法包括使用配置选项、模块化设计和优化配置参数,图形裁剪工具如makeme... 目录简介一、 裁剪的原因二、裁剪的方法三、图形裁剪工具四、操作说明五、make menuconfig

详解Java中的敏感信息处理

《详解Java中的敏感信息处理》平时开发中常常会遇到像用户的手机号、姓名、身份证等敏感信息需要处理,这篇文章主要为大家整理了一些常用的方法,希望对大家有所帮助... 目录前后端传输AES 对称加密RSA 非对称加密混合加密数据库加密MD5 + Salt/SHA + SaltAES 加密平时开发中遇到像用户的

React实现原生APP切换效果

《React实现原生APP切换效果》最近需要使用Hybrid的方式开发一个APP,交互和原生APP相似并且需要IM通信,本文给大家介绍了使用React实现原生APP切换效果,文中通过代码示例讲解的非常... 目录背景需求概览技术栈实现步骤根据 react-router-dom 文档配置好路由添加过渡动画使用