如何实现跨标签页通讯

在这里插入图片描述

什么是跨标签页通讯

同一浏览器,可以打开多个标签页,跨标签页通讯就是,一个标签页能够发消息给另一标签页。

有哪些实现方案

  1. localStorage (window.onstorage事件监听)
  2. BroadcastChannel(广播)
  3. ServiceWorker (代理服务线程)
  4. SharedWorker + 轮询
  5. indexedDB + 轮询
  6. cookie + 轮询
  7. window.open + window.postMessage()
  8. WebSocket + 后端服务

方案一:localStorage

基于storage事件

页面一(localStorage1.html):

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>localStorage1</title>
</head>
<body><h1>localStorage1</h1><ul id="ul"></ul><script>/** 更新视图*/function changeView(){const ul = document.getElementById('ul');ul.innerHTML = '';for(let i = 0; i < localStorage.length; i++){const key = localStorage.key(i);const value = localStorage.getItem(key);const li = document.createElement('li');li.textContent = `${key}: ${value}`;ul.appendChild(li);}}/** 数据更新-更新视图*/function changeData(key,value){localStorage.setItem(key,value);changeView();}/** 更新localStorage中数据 */changeData('name','张三')changeData('age','18')</script>
</body>
</html>

页面二(localStorage2.html):

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>localStorage1</title>
</head>
<body><h1>localStorage2</h1><ul id="ul"></ul><script>function changeView(){const ul = document.getElementById('ul');ul.innerHTML = '';for(let i = 0; i < localStorage.length; i++){const key = localStorage.key(i);const value = localStorage.getItem(key);const li = document.createElement('li');li.textContent = `${key}: ${value}`;ul.appendChild(li);}}changeView();//当localStorage发生变化时,会触发storage事件window.addEventListener('storage',changeView)</script>
</body>
</html>

方案二:BroadcastChannel

BroadcastChannel可以创建一个用于广播的通信频道,当所有页面都监听同一频道的消息时,其中某一个页面通过它发送的消息就会被其他页面接收到,前提是同源页面。

页面1(channel1.html):

 <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title></head><body><h1>BroadcastChannel1-Tom</h1><p>接收消息:</p><p id="message" style="white-space: pre;"></p><input type="text" name="message" id="messageInput"><button onclick="postMessage()">发送消息</button><script>const messageElement = document.getElementById('message');const messageInput = document.getElementById('messageInput');const bc = new BroadcastChannel('channel');bc.onmessage = function(e) {console.log('收到消息:', e.data);messageElement.textContent += '\n'+e.data;}function postMessage() {console.log('发送消息');const message = messageInput.value;bc.postMessage(message);messageInput.value = '';}</script></body></html>

页面2(channel1.html):

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><h1>BroadcastChannel2-Jerry</h1><p>接收消息:</p><p id="message" style="white-space: pre;"></p><input type="text" name="message" id="messageInput"><button onclick="postMessage()">发送消息</button><script>const messageElement = document.getElementById('message');const messageInput = document.getElementById('messageInput');const bc = new BroadcastChannel('channel');bc.onmessage = function(e) {console.log('收到消息:', e.data);messageElement.textContent += '\n'+e.data;}function postMessage() {console.log('发送消息');const message = messageInput.value;bc.postMessage(message);messageInput.value = '';}</script>
</body>
</html>

方案三:ServiceWorker

Service worker 本质上充当 Web 应用程序、浏览器与网络(可用时)之间的代理服务器。

sw.js文件-代理服务器

// 消息会先到达这里,然后发送到其他客户端
self.addEventListener('message', async (event)=> {// 首先获取所有注册了serviceWorker的客户端self.clients.matchAll().then((clients)=>{// 遍历所有客户端       clients.forEach((client)=>{// 向每个客户端发送消息client.postMessage(event.data);})})
});

service1.html文件-客户端1

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><h1>service1</h1><input type="text" id="content"><button id="bt">发送</button><script>/**注册serviceWorker*/navigator.serviceWorker.register('sw.js').then(function(registration){console.log('service worker 注册成功');})const bt = document.getElementById('bt');bt.addEventListener('click',function(){const message = document.getElementById('content').value;// controller控制器发送消息navigator.serviceWorker.controller.postMessage(message);})</script>
</body>
</html>

service2.html文件-客户端2

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><h1>service1</h1><script>/**注册同一serviceWorker*/navigator.serviceWorker.register('sw.js').then(function(registration){console.log('service worker 注册成功');})//监听onmessage事件navigator.serviceWorker.onmessage = function(event){console.log('收到消息',event.data);}</script>
</body>
</html>

方案四:SharedWorker + 轮询

SharedWorkerWorker的一种,它允许你在多个页面之间共享一个Worker

shared.js(worker)

let data = "";//存储用户发送的信息
onconnect = (event) => {const port = event.ports[0];//获取客户端端口port.onmessage = (event) => {if (event.data==='get') {port.postMessage(data);//向客户端发送消息}else{data = event.data;//将用户发送的信息存储到data变量中}}
}

shared1.html(页面一)

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><h1>shared1</h1><input type="text" id="content"><button id="btn">发送</button><script>const btn = document.getElementById('btn');const content = document.getElementById('content');const message = document.getElementById('message')// 创建SharedWorkerconst shared = new SharedWorker('shared.js');btn.onclick = function(){// 向SharedWorker发送消息shared.port.postMessage(content.value);content.value = '';}</script>
</body>
</html>

shared2.html(页面二)

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><h1>shared1</h1><input type="text" id="content"><button id="btn">发送</button><script>const btn = document.getElementById('btn');const content = document.getElementById('content');const message = document.getElementById('message')// 创建SharedWorkerconst shared = new SharedWorker('shared.js');btn.onclick = function(){// 向SharedWorker发送消息shared.port.postMessage(content.value);content.value = '';}</script>
</body>
</html>

方案五:IndexedDB+轮询

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

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

相关文章

【积累】list

List 一个list转为二维数组&#xff0c;五个一组 List<List<String>> lists Lists.partition(list,5);删除list中的元素 删除下标以及定位到遍历的位置 for(int i 0, len list.size(); i < len; i){ if(list.get(i) 1){ list.remove(i); len--;i--;} …

C语言经典算法-9

文章目录 其他经典例题跳转链接46.稀疏矩阵47.多维矩阵转一维矩阵48.上三角、下三角、对称矩阵49.奇数魔方阵50.4N 魔方阵51.2(2N1) 魔方阵 其他经典例题跳转链接 C语言经典算法-1 1.汉若塔 2. 费式数列 3. 巴斯卡三角形 4. 三色棋 5. 老鼠走迷官&#xff08;一&#xff09;6.…

pytest框架的封装以及用例管理框架

pytest框架的封装以及用例管理框架 公共类统一封装requests_util02.pytest_api01.py 自动化测试的基础自动化测试的介入点自动化测试和手工测试占比自动化实施过程 pytest元素定位元素定位查找元素定位的方式通过 ID 定位通过 Name 定位通过 Class Name 定位通过 Tag Name 定位…

唯众物联网安装调试员实训平台物联网一体化教学实训室项目交付山东技师学院

近日&#xff0c;山东技师学院物联网安装调试员实训平台及物联网一体化教学实训室采购项目已顺利完成交付并投入使用&#xff0c;标志着学院在物联网技术教学与实践应用方面迈出了坚实的一步。 山东技师学院作为国内知名的技师培养摇篮&#xff0c;一直以来致力于为社会培养高…

windows11 openssh服务开启;第三方ping不通局域网windows电脑;ssh连接内部ubuntu系统

参考&#xff1a;https://blog.csdn.net/2301_77554343/article/details/134328867 1、windows11 openssh开启 1&#xff09;我这边可选功能在设置-系统里面&#xff1b;其他网上看在应用下&#xff1b;添加可选openssh服务器安装 2&#xff09;安装后打开&#xff0c;管理员…

光伏户用开发技巧

一、开发户用光伏的技巧有哪些&#xff1f; 1.项目可行性分析 电站开发前需要先进行可行性分析&#xff0c;从当地的气象条件、电网的接入能力、政策环境等方便分析。可以自行收集数据分析&#xff0c;也可以邀请专业机构进行评估。 2.选址和电站设计 光伏电站的选址&#…

agent利用知识来做规划:《KnowAgent: Knowledge-Augmented Planning for LLM-Based Agents》笔记

文章目录 简介KnowAgent思路准备知识Action Knowledge的定义Planning Path Generation with Action KnowledgePlanning Path Refinement via Knowledgeable Self-LearningKnowAgent的实验结果 总结参考资料 简介 《KnowAgent: Knowledge-Augmented Planning for LLM-Based Age…

Leetcode 3093. Longest Common Suffix Queries

Leetcode 3093. Longest Common Suffix Queries 1. 解题思路2. 代码实现 题目链接&#xff1a;3093. Longest Common Suffix Queries 1. 解题思路 这一题的话思路上其实就是一个Trie树的变体。 对于每一个wordsQuery当中的word&#xff0c;我们要在wordsContainer当中获取答…

Redis 教程系列之Redis 简介(一)

Redis&#xff1a; Remote DIctionary Server(Redis) 是一个由 Salvatore Sanfilippo 写的 key-value 存储系统&#xff0c;是跨平台的非关系型数据库。 Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value…

Spring Cloud四:微服务治理与安全

Spring Cloud一&#xff1a;Spring Cloud 简介 Spring Cloud二&#xff1a;核心组件解析 Spring Cloud三&#xff1a;API网关深入探索与实战应用 文章目录 一、服务注册中心的选型与最佳实践1. 主流服务注册中心概述2. 最佳实践建议(1)、选型建议(2)、高可用性与稳定性1). 高可…

Linux安装iptables 防火墙

安装iptables Ubuntu&#xff1a; sudo apt-get update sudo apt-get install iptables Centos&#xff1a; sudo yum install iptables 开启&#xff1a;service iptables start 关闭&#xff1a;service iptables stop dpkg -l | grep iptables --查看iptables 是否安装

北京密云广电许可证办理要求与流程

北京密云广电许可证办理攻略&#xff1a;要求与流程全解析 一、引言 各位老板好&#xff0c;我是经典世纪胡云帅&#xff0c;随着广播电视行业的快速发展&#xff0c;越来越多的企业和个人希望进入这一领域&#xff0c;开展节目制作、传播等业务。而在北京密云&#xff0c;这一…

二进制王国(蓝桥杯备赛)【sort/cmp的灵活应用】

二进制王国 题目链接 https://www.lanqiao.cn/problems/17035/learning/?contest_id177 题目描述 思路 这里就要灵活理解字典序排列&#xff0c;虽然string内置可以直接比较字符串字典序&#xff0c;但是在拼接时比较特殊&#xff0c;比如 11的字典序小于110&#xff0c;但…

HTTP --- 下

目录 1. HTTP请求方式 1.1. HTML 表单 1.2. GET && POST方法 1.2.1. 用 GET 方法提交表单数据 1.2.2. 用 POST 方法提交表单数据 1.2.3. 总结 1.3. 其他方法 2. HTTP的状态码 2.1. 重定向 2.1.1. 临时重定向 && 永久重定向 2.1.2. 302 &&…

【Vue3笔记02】Vue3项目工程中使用axios网络请求库实现前后端数据通信

这篇文章,主要介绍Vue3项目工程中如何使用axios网络请求库实现前后端数据通信【知识星球】。 目录 一、axios依赖 1.1、下载axios依赖 1.2、创建axios工具类

【MySQL系列】Public Key Retrieval is not allowed

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Python灰帽子网络安全实践

教程介绍 旨在降低网络防范黑客的入门门槛&#xff0c;适合所有中小企业和传统企业。罗列常见的攻击手段和防范方法&#xff0c;让网站管理人员都具备基本的保护能力。Python 编程的简单实现&#xff0c;让网络运维变得更简单。各种黑客工具的理论和原理解剖&#xff0c;让人知…

c++结束输入

在C语言中&#xff0c;停止输入通常意味着结束从标准输入&#xff08;通常是键盘&#xff09;读取数据的操作。这通常通过检测一个特定的输入条件来实现&#xff0c;如一个特殊的EOF&#xff08;文件结束&#xff09;标记&#xff0c;或者当读取某些特定的值时结束循环。 以下…

css与鼠标光标指针相关的属性有哪些?

CSS中与鼠标光标相关的属性以下几个&#xff1a; cursor: 设置鼠标光标的样式。常见的取值有&#xff1a; auto&#xff1a;浏览器自动决定光标样式。pointer&#xff1a;手型光标&#xff0c;表示链接可点击。default&#xff1a;默认光标样式。text&#xff1a;文本光标&…

Acwing算法提高课-DP-数字三角形模型

摘花生 见另一篇文章&#xff1a; Acwing数学与简单DP&#xff08;二&#xff09; 最低通行费 原题链接&#xff1a;https://www.acwing.com/problem/content/1020/ 类似于上面的摘花生&#xff0c;不过摘花生求的是集合的MAX&#xff0c;最低通行费求的是集合的MIN。 但是&am…