如何实现跨标签页通讯

在这里插入图片描述

什么是跨标签页通讯

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

有哪些实现方案

  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,一经查实,立即删除!

相关文章

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…

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

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

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

北京密云广电许可证办理攻略&#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 &&…

【MySQL系列】Public Key Retrieval is not allowed

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

Python灰帽子网络安全实践

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

基于Matlab的眼底图像血管分割,Matlab实现

博主简介&#xff1a; 专注、专一于Matlab图像处理学习、交流&#xff0c;matlab图像代码代做/项目合作可以联系&#xff08;QQ:3249726188&#xff09; 个人主页&#xff1a;Matlab_ImagePro-CSDN博客 原则&#xff1a;代码均由本人编写完成&#xff0c;非中介&#xff0c;提供…

车道线检测论文:《Ultra Fast Structure-aware Deep Lane Detection》

该论文标题为《Ultra Fast Structure-aware Deep Lane Detection》&#xff0c;作者是浙江大学计算机科学与技术学院的Zequn Qin、Huanyu Wang和Xi Li。论文提出了一种新颖的、简单而有效的车道检测方法&#xff0c;旨在解决具有挑战性场景下的车道检测问题&#xff0c;并实现极…

借用QStyledItemDelegate 在DataView中创建各种子控件

在Model/View 中&#xff0c;二维表格的输入方式可能各种各样&#xff0c;我们需要在单元格嵌入各种类型控件&#xff0c;但是能把各种控件整合一个委托类吗&#xff1f;本文进行了尝试。将创建各种控件的逻辑整合到一个委托类。效果图如下&#xff1a; 本文实现了在DataView 的…

【SpringMVC】知识汇总

SpringMVC 短暂回来&#xff0c;有时间就会更新博客 文章目录 SpringMVC前言一、第一章 SpingMVC概述二、SpringMVC常用注解1. Controller注解2. RequestMapping注解3. ResponseBody注解4. RequestParam5. EnableWebMvc注解介绍6. RequestBody注解介绍7. RequestBody与RequestP…

Echarts功能记录

基础配置 工具箱toolbox 对应功能 案例中使用到的第三方脚本

解决Animate.css动画效果无法在浏览器运行问题

背景 在开发官方网站的时候&#xff0c;临时更换了电脑&#xff0c;发现原本正常的动画效果突然不动了。 经过 chrome、Microsoft Edge都无法运行。 Animate.css | A cross-browser library of CSS animations. 问题排查 通过审查元素后发现类名是注入并且生效的。 验证 然…

【图解物联网】第3章 物联网设备

3.1 设备——通向显示世界的接口 3.1.1 为什么要学习设备的相关知识 经过前两章的学习&#xff0c;想必各位读者已经掌握物联网这个词描绘出的世界和用于实现物联网的系统架构了。基于这点&#xff0c;这一章将会为大家介绍在物联网世界中起着核心作用的因素&#xff0c;即设…

atoi函数(想要彻底了解atoi函数,那么看这一篇就足够了!)

前言&#xff1a;在学习C语言的时候&#xff0c;我们知道每个字符都有其所对应的ASCII码值&#xff0c;当我们使用49来打印字符时&#xff0c;打印出来的就是数字字符 ‘ 1 ’&#xff0c;那么字符能否直接被转换成对应的整型数字呢&#xff1f;答案是当然可以&#xff0c;这时…