如何实现跨标签页通讯

在这里插入图片描述

什么是跨标签页通讯

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

有哪些实现方案

  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.rhkb.cn/news/280428.html

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

相关文章

opengl日记10-opengl使用多个纹理示例

文章目录 环境代码CMakeLists.txt文件内容不变。fragmentShaderSource.fsvertexShaderSource.vsmain.cpp 总结 环境 系统&#xff1a;ubuntu20.04opengl版本&#xff1a;4.6glfw版本&#xff1a;3.3glad版本&#xff1a;4.6cmake版本&#xff1a;3.16.3gcc版本&#xff1a;10.…

图片编辑器中实现文件上传的三种方式和二进制流及文件头校验文件类型

背景 最近在 vue-design-editor 开源项目中实现 psd 等多种文件格式上传解析成模板过程中, 发现搞定设计文件上传没有使用 input 实现文件上传, 所以我研究了一下相关技术, 总结了以下三种文件上传方法 input 文件选择window.showOpenFilePicker 和 window.showDirectoryPicke…

零基础入门数据挖掘系列之「建模调参」

摘要&#xff1a;对于数据挖掘项目&#xff0c;本文将学习如何建模调参&#xff1f;从简单的模型开始&#xff0c;如何去建立一个模型&#xff1b;如何进行交叉验证&#xff1b;如何调节参数优化等。 建模调参&#xff1a;特征工程也好&#xff0c;数据清洗也罢&#xff0c;都是…

python日常刷题(一)

前言&#xff1a;本文记录2024年3月11日至2024年3月19日牛客网所做的基础题目&#xff08;错题本&#xff09;&#xff1a; &#x1f3ac;个人简介&#xff1a;努力学习ing &#x1f4cb;本专栏&#xff1a;python日常刷题 &#x1f380;CSDN主页&#xff1a;愚润求学 文章目录…

VueUse常见方法使用

npm i vueuse/core 1、useDebounceFn 节流防抖 import { useDebounceFn } from vueuse/core<button type"button" class"search" click"query">查询</button>// 查询 获取table数据const query2 async () > {try {const res …

ETH Gas 之 Base Fee Priority Fee

前情回顾 ETH网络 之 Gas EIP-1559 EIP-1559 EIP-1559是以太坊改进提案&#xff08;Ethereum Improvement Proposal&#xff09;&#xff0c;旨在改进以太坊的交易费用机制。该提案引入了一种新的交易费用模型&#xff0c;以提高交易费用的可预测性和网络的效率。我们本文各…

【机器学习】基于果蝇算法优化的BP神经网络分类预测(FOA-BP)

目录 1.原理与思路2.设计与实现3.结果预测4.代码获取 1.原理与思路 【智能算法应用】智能算法优化BP神经网络思路【智能算法】果蝇算法&#xff08;FOA&#xff09;原理及实现 2.设计与实现 数据集&#xff1a; 多输入多输出&#xff1a;样本特征24&#xff0c;标签类别4。…

(官网安装) 基于CentOS 7安装MangoDB和MangoDB Shell

前言 查了很多资料都不靠谱&#xff0c;在安装过程中遇到很多的坑&#xff0c;mangoDB 服务重视起不来&#xff1b;出现了很多难以解决的报错&#xff0c;现在把安装过程中遇到的问题&#xff0c;和如何闭坑说一下&#xff0c;很多时候都是准备工作不足导致的&#xff1b;很多方…

TinTin Web3 Bounty 挑战杯开启,Sui 向你发出挑战邀请

以下文章来源于TinTinLand &#xff0c;作者TinTinLand。 2024 年开年最火的是什么&#xff1f; 对 Web3 来说&#xff0c;Bounty 任务应该是普通人获得行业“一杯羹”的重要捷径&#xff01; 通过深入学习各类 Web3 技术&#xff0c;凭借实战锻炼开发创新项目&#xff0c;就…

【运维笔记】VM 记录一次centos虚拟机和宿主机之间ping不通的问题

问题描述 环境&#xff1a;centos7&#xff0c;静态ipVM版本&#xff1a;VMware Workstation 16 pro&#xff0c;网络为nat映射模式问题&#xff1a; 一开始&#xff0c;虚拟机可以ping通宿主机&#xff0c;也可以ping通&#xff0c;也可以ping通外网&#xff08;如 ping www.…

海外云手机如何帮助亚马逊引流?

随着全球化的推进&#xff0c;出海企业和B2B外贸企业越来越注重海外市场的开拓&#xff0c;这已成为企业争夺市场份额的重要策略。本文将重点探讨海外云手机在优化亚马逊店铺引流方面的作用和优势。 海外云手机是一种在云端运行的虚拟手机&#xff0c;能够在单一芯片上多开几个…

centos 环境部署

一、安装redis 1. 升级 GCC 最直接的解决方式是升级你的 GCC 编译器到支持 C11 标准的版本。CentOS 7 默认的 GCC 版本较旧&#xff0c;可能不支持 _Atomic。你可以通过以下步骤升级 GCC&#xff1a; 启用 CentOS 的 Software Collections (SCL) 仓库&#xff0c;该仓库提供了…

软件的安装与卸载(YUM)

YUM&#xff1a;yum 是一个方便的"应用商店"&#xff0c;你可以通过它轻松地安装、更新和删除软件包&#xff0c;就像从应用商店中下载和安装应用程序一样。&#xff08;这个得用root身份&#xff0c;普通用户权限不够&#xff09; 常用命令&#xff1a; 1.安装软件…

【论文阅读】DiffSpeaker: Speech-Driven 3D Facial Animation with Diffusion Transformer

DiffSpeaker: 使用扩散Transformer进行语音驱动的3D面部动画 code&#xff1a;GitHub - theEricMa/DiffSpeaker: This is the official repository for DiffSpeaker: Speech-Driven 3D Facial Animation with Diffusion Transformer paper&#xff1a;https://arxiv.org/pdf/…

企业如何选择一个开源「好」项目?

开源 三句半 oss-roast 需求明确是关键 风险考量要周全 开源虽好不白捡 别忘合规&#xff01; 显然&#xff0c;开源已成为一股不可阻挡的洪流&#xff0c;企业拥抱开源&#xff0c;积极参与开源项目不仅是响应技术潮流的必然选择&#xff0c;更是实现自身技术创新、市场拓展等…

Golang 异步(bsd/linux)io

Golang 异步(bsd/linux)io 在日常开发中&#xff0c;读写文件的底层调用函数是syscall.Read/Write。一切都是围绕这两个函数展开的&#xff0c;不过有时候需要或者就是单纯想异步执行。liburing是linux上一个很好的原生异步io库&#xff0c;这里需要适配bsd派系的系统&#xf…

自动化的免下车服务——银行、餐厅、快餐店、杂货店

如果您在20世纪70年代和2020年分别驾车经过免下车服务餐厅&#xff08;汽车穿梭餐厅&#xff09;&#xff0c;您会发现&#xff0c;唯一的不同是排队的车型。50多年来&#xff0c;免下车技术一直为我们提供着良好的服务&#xff0c;但现在也该对它进行现代化改造了。 乘着AI和自…

IOS/Android App备案(uniapp)

IOS/App备案 IOS备案Android备案 IOS备案 准备好p12证书即可 链接: https://aitoolnav.caichuangkeji.com/#/AppMd5 Android备案 上DCLOUD开发者中心&#xff0c;找到相关应用后&#xff0c;直接查看证书即可获取到MD5 公钥&#xff1a;先根据上述页面下载证书&#xff0c;…

ping 通ip,ping 不通域名

在linux 系统中&#xff0c;ping 通ip,ping 不通对应的域名时&#xff0c;可直接修改系统配置文件 vi /etc/hosts 加入 ip 域名

程序员们的“薪饭碗”:学会鸿蒙开发以后有哪些就业方向?

近期&#xff0c;鸿蒙相关内容一直是IT行业热聊话题。先是徐大嘴宣布鸿蒙 Next版本不在兼容Android&#xff0c;然后就是各大互联网公司纷纷加入到鸿蒙原生开发的队列&#xff0c;再然后网传出鸿蒙开发岗位薪资与需求了突增&#xff0c;超出了一些传统开发岗位的需求与薪资水平…