当前位置: 首页 > news >正文

浏览器跨tab页面通信方式总结

需求:

浏览器不同 tab 标签页之间是独立的, 如果要通信必须通过特殊手段来实现跨标签页通信。 

1.StorageEvent 事件

当一个标签页 localStorage 变化时(sessionStorage 无效),同源下另一个或其他所有标签页使用 DOM2 监听 storage 事件监听,不能使用 DOM0 监听,最新 Chrome 不支持。

StorageEvent:当前页面使用的 storage 被其他页面修改时会触发 StorageEvent 事件。

事件在同一个域下的不同页面之间触发,即在 A 页面注册了 storge 的监听处理,只有在跟 A 同域名下的 B 页面操作 storage 对象,A 页面才会被触发 storage 事件

示例代码:

// 在一个标签页中设置localStorage
window.localStorage.setItem("sendMessage", "Hello,Bro!");// 在同源下另一个或所有的标签页下所有数据 监听storage 事件
window.addEventListener("storage", e => {console.log(e.key);console.log(e.oldValu);console.log(e.newValue);if (e.key === "sendMessage") {console.log(e.newValue); // Hello,Bro!}
});

事件对象包含以下属性:

2.window.open 配合 window.postMessage

otherWindow.postMessage(message, targetOrigin, [transfer]);

message:要发送的消息,可以是任意类型的数据。

targetOrigin:通过窗口的 origin 属性来指定哪些窗口能接收到消息事件,其值可以是字符串"_"(表示无限制)或者一个 URI。在发送消息的时候,如果目标窗口的协议、主机地址或端口这三者的任意一项不匹配 targetOrigin 提供的值,那么消息就不会被发送;只有三者完全匹配,消息才会被发送。这个机制用来控制消息可以发送到哪些窗口;例如,当用 postMessage 传送密码时,这个参数就显得尤为重要,必须保证它的值与这条包含密码的信息的预期接受者的 origin 属性完全一致,来防止密码被恶意的第三方截获。如果你明确的知道消息应该发送到哪个窗口,那么请始终提供一个有确切值的 targetOrigin,而不是 _。不提供确切的目标将导致数据泄露到任何对数据感兴趣的恶意站点。

transfer:可选的,是一串和 message 同时传递的 Transferable 对象。这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。

targetOrigin 值可以是以下任意一个:

一个 URI,表示该 URI 所表示的源。

示例代码:

// 在一个标签页中发送消息
const baidu = window.open("baidu.com");
baidu.postMessage("Hello,Bro!", "*");
// 在window.open()打开的另一个标签页中接受消息
window.addEventListener("message", event => {console.log("Received", event.data); // Received Hello,Bro!
});

3.BroadcastChannel(webworker 可用)

BroadcastChannel 接口代理了一个命名频道,可以让指定 origin 下的任意 browsing context 来订阅它。它允许同源的不同浏览器窗口,Tab 页,frame 或者 iframe 下的不同文档之间相互通信。通过触发一个 message 事件,消息可以广播到所有监听了该频道的 BroadcastChannel 对象。

BroadcastChannel 顾名思义 广播频道,这个 WEB API 设计用来跨标签页之间通信

属性

BroadcastChannel.name 频道名称,返回 DOMString。

事件处理程序

BroadcastChannel.onmessage(),或 BroadcastChannel.addEventListener('message',callback) 事件处理器,用于定义当该对象上触发了 message 事件时要执行的函数。BroadcastChannel.onmessageerror(),或 BroadcastChannel.addEventListener('messageerror', callback) 事件处理器,用于定义当该对象上触发了类型为 MessageError 的 MessageEvent 事件时要执行的函数。当接收到一条无法反序列化的消息时会触发此事件。

方法

BroadcastChannel.postMessage() 向所有监听了相同频道的 BroadcastChannel 对象发送一条消息,消息内容可以是任意类型的数据。BroadcastChannel.close() 关闭频道对象,告诉它不要再接收新的消息,并允许它最终被垃圾回收。

示例代码:

// 在一个标签页中发送消息
const channel = new BroadcastChannel("myChannel");
channel.postMessage("Hello,Bro!");
// 在另一个或其他所有标签页中接受同频道消息
const channel = new BroadcastChannel("myChannel");
channel.addEventListener("message", event => {console.log("Received", event.data); // Hello,Bro!
});
// 断开频道连接
channel.close();

4.SharedWorker(注意兼容性)

创建一个执行指定 url 脚本的共享 web worker。如果要使 SharedWorker 连接到多个不同的页面,这些页面必须是同源的(相同的协议、host 以及端口)。

示例代码:

// worker.js
onconnect = function (e) {var port = e.ports[0];port.addEventListener("message", function (e) {var workerResult = "Result: " + e.data;port.postMessage(workerResult);});port.start(); // 使用addEventListener 要手动加上. 如果使用onmessage则可以省略
};
// 在不同页面中创建共享 web worker
this.shareWorker = new SharedWorker("./worker.js");
// 接受信息
this.shareWorker.port.onmessage = e => {console.log(e.data);
};
// 发送信息,可以传递任何东西
this.shareWorker.port.postMessage({type: "notifyTab",payload: {}
});

5.其他一些偏方

IndexedDB 定时器轮询,cookie 定时器轮询,Websocket 等

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【iOS】OC类与对象的本质分析
  • 【IEEE出版】第四届能源工程与电力系统国际学术会议(EEPS 2024)
  • 河南萌新联赛2024第(一)场:河南农业大学 A D F G H I K
  • html+canvas 实现签名功能-手机触摸
  • GraphRAG+ollama+LM Studio+chainlit
  • 怎么剪辑音频文件?4款适合新的音频剪辑软件
  • Spring Boot项目中使用MyBatis Generator (MBG) 自动生成Mapper文件
  • LinuxShell编程2——shell搭建Discuzz论坛网站
  • 框架设计MVP
  • Adobe国际认证详解-网页设计认证专家行业应用场景解析
  • 数据仓库中事实表设计的关键步骤解析
  • 【Langchain大语言模型开发教程】模型、提示和解析
  • 微服务实战系列之玩转Docker(一)
  • # Redis 入门到精通(七)-- redis 删除策略
  • [SUCTF 2019]EasySQL1
  • 【刷算法】从上往下打印二叉树
  • 78. Subsets
  • Brief introduction of how to 'Call, Apply and Bind'
  • hadoop集群管理系统搭建规划说明
  • java B2B2C 源码多租户电子商城系统-Kafka基本使用介绍
  • Java比较器对数组,集合排序
  • jQuery(一)
  • js如何打印object对象
  • Linux Process Manage
  • linux安装openssl、swoole等扩展的具体步骤
  • Python学习之路13-记分
  • Ruby 2.x 源代码分析:扩展 概述
  • vue从创建到完整的饿了么(11)组件的使用(svg图标及watch的简单使用)
  • Webpack 4x 之路 ( 四 )
  • 第2章 网络文档
  • 翻译--Thinking in React
  • 嵌入式文件系统
  • 我从编程教室毕业
  • 我有几个粽子,和一个故事
  • 资深实践篇 | 基于Kubernetes 1.61的Kubernetes Scheduler 调度详解 ...
  • ​VRRP 虚拟路由冗余协议(华为)
  • # centos7下FFmpeg环境部署记录
  • # 执行时间 统计mysql_一文说尽 MySQL 优化原理
  • (04)odoo视图操作
  • (八)Flink Join 连接
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (附源码)springboot课程在线考试系统 毕业设计 655127
  • (论文阅读11/100)Fast R-CNN
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (十八)devops持续集成开发——使用docker安装部署jenkins流水线服务
  • (四)stm32之通信协议
  • (算法)Game
  • (学习日记)2024.03.25:UCOSIII第二十二节:系统启动流程详解
  • (一)pytest自动化测试框架之生成测试报告(mac系统)
  • (转)Linq学习笔记
  • (转)PlayerPrefs在Windows下存到哪里去了?
  • (转载)Linux 多线程条件变量同步
  • .cn根服务器被攻击之后
  • .NET 中各种混淆(Obfuscation)的含义、原理、实际效果和不同级别的差异(使用 SmartAssembly)