【前端技术】标签页通讯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

相关文章

DNS查询的利器! linux的dig命令基本用法详解

《DNS查询的利器!linux的dig命令基本用法详解》dig命令可以查询各种类型DNS记录信息,下面我们将通过实际示例和dig命令常用参数来详细说明如何使用dig实用程序... dig(Domain Information Groper)是一款功能强大的 linux 命令行实用程序,通过查询名称服务器并输

Python 函数详解:从基础语法到高级使用技巧

《Python函数详解:从基础语法到高级使用技巧》本文基于实例代码,全面讲解Python函数的定义、参数传递、变量作用域及类型标注等知识点,帮助初学者快速掌握函数的使用技巧,感兴趣的朋友跟随小编一起... 目录一、函数的基本概念与作用二、函数的定义与调用1. 无参函数2. 带参函数3. 带返回值的函数4.

javaSE类和对象进阶用法举例详解

《javaSE类和对象进阶用法举例详解》JavaSE的面向对象编程是软件开发中的基石,它通过类和对象的概念,实现了代码的模块化、可复用性和灵活性,:本文主要介绍javaSE类和对象进阶用法的相关资... 目录前言一、封装1.访问限定符2.包2.1包的概念2.2导入包2.3自定义包2.4常见的包二、stati

SpringBoot结合Knife4j进行API分组授权管理配置详解

《SpringBoot结合Knife4j进行API分组授权管理配置详解》在现代的微服务架构中,API文档和授权管理是不可或缺的一部分,本文将介绍如何在SpringBoot应用中集成Knife4j,并进... 目录环境准备配置 Swagger配置 Swagger OpenAPI自定义 Swagger UI 底

C# async await 异步编程实现机制详解

《C#asyncawait异步编程实现机制详解》async/await是C#5.0引入的语法糖,它基于**状态机(StateMachine)**模式实现,将异步方法转换为编译器生成的状态机类,本... 目录一、async/await 异步编程实现机制1.1 核心概念1.2 编译器转换过程1.3 关键组件解析

Linux权限管理与ACL访问控制详解

《Linux权限管理与ACL访问控制详解》Linux权限管理涵盖基本rwx权限(通过chmod设置)、特殊权限(SUID/SGID/StickyBit)及ACL精细授权,由umask决定默认权限,需合... 目录一、基本权限概述1. 基本权限与数字对应关系二、权限管理命令(chmod)1. 字符模式语法2.

基于Python Playwright进行前端性能测试的脚本实现

《基于PythonPlaywright进行前端性能测试的脚本实现》在当今Web应用开发中,性能优化是提升用户体验的关键因素之一,本文将介绍如何使用Playwright构建一个自动化性能测试工具,希望... 目录引言工具概述整体架构核心实现解析1. 浏览器初始化2. 性能数据收集3. 资源分析4. 关键性能指

Go语言使用select监听多个channel的示例详解

《Go语言使用select监听多个channel的示例详解》本文将聚焦Go并发中的一个强力工具,select,这篇文章将通过实际案例学习如何优雅地监听多个Channel,实现多任务处理、超时控制和非阻... 目录一、前言:为什么要使用select二、实战目标三、案例代码:监听两个任务结果和超时四、运行示例五

Linux线程同步/互斥过程详解

《Linux线程同步/互斥过程详解》文章讲解多线程并发访问导致竞态条件,需通过互斥锁、原子操作和条件变量实现线程安全与同步,分析死锁条件及避免方法,并介绍RAII封装技术提升资源管理效率... 目录01. 资源共享问题1.1 多线程并发访问1.2 临界区与临界资源1.3 锁的引入02. 多线程案例2.1 为

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我