» 介绍

浏览器窗口通信是比较常见的场景,比如登录、购物、在线聊天等等,下面简单介绍几种常见的通信方式和使用方法。


1.WebSocket

html5提供的全双工通讯的协议,浏览器和服务器之间建立一条不受限的双向通信的通道,双向数据传输,需要服务端支持。

使用方法可参考:nodejs搭建websocket服务实现多页面通信


2.StorageEvent

简单有效的方式,页面A通过storage存储消息,页面B监听storage即可捕获消息。

pageA.html:

<body>
<input type="text" id="msg">
<button id="send">发送</button>
<script>send.onclick = function () {let msg = document.getElementById("msg").valuelocalStorage.setItem('message', JSON.stringify({message: msg,from: 'pageA.html',date: Date.now()}))}</script>
</body>

pageB.html:

<body>
收到了消息:<span id="text"></span>
<script>window.addEventListener('storage', function (e) {// console.log(e.key, e.newValue, e.oldValue)let msg = JSON.parse(e.newValue)document.getElementById('text').innerText = msg.message})</script>
</body>

3.postMessage

支持跨域通信,需要获取打开窗口的句柄(对象),建立联系,安全地实现跨源通信。

pageA.html:

<body>
<button id="openw">打开B页面</button>
<br>
<input type="text" id="msg">
<button id="send">发送</button>
<script>let newWindow = nullopenw.onclick = function () {console.log(333)newWindow = window.open('pageB.html')}send.onclick = function () {let msg = document.getElementById("msg").valueif (newWindow)newWindow.postMessage(msg)}</script>
</body>

pageB.html:

<body>
收到了消息:<span id="text"></span>
<script>window.addEventListener('message', function (e) {document.getElementById('text').innerHTML = e.data})</script>
</body>

参考文档:https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage


4.SharedWorker

实现一个在浏览器后台运行的共享worker,页面通过该worker进行连接和信息的传递。同源

本地不支持,需要放到服务器。( webstorm可在浏览器中打开,vscode使用live server插件)测试。

worker.js:

let portList = [];onconnect = function (e) {let port = e.ports[0];if (portList.indexOf(port) < 0)portList.push(port);port.onmessage = function (e) {boardCast(e.data);};port.start();
};function boardCast(data) {portList.forEach(port => port.postMessage(data));
}

pageA.html:

<body>
<input type="text" id="msg">
<button id="send">发送</button>
<script>if (!!window.SharedWorker) {let myWorker = new SharedWorker("worker.js");send.onclick = function () {let msg = document.getElementById("msg").valuemyWorker.port.postMessage(msg);}myWorker.port.start()} else {alert("当前浏览器不支持webworker!")}</script>
</body>

pageB.html:

<body>
收到了消息:<span id="text"></span>
<script>if (!!window.SharedWorker) {let myWorker = new SharedWorker("worker.js");myWorker.port.onmessage = function (e) {document.getElementById('text').innerText = e.data}myWorker.port.start()} else {alert("当前浏览器不支持webworker!")}</script>
</body>

参考文档:https://developer.mozilla.org/zh-CN/docs/Web/API/SharedWorker


5.BroadcastChannel

实现同 源 下浏览器不同窗口,Tab页,frame或者 iframe 下的 浏览器上下文 (通常是同一个网站下不同的页面)之间的简单通讯。

pageA.html:

<body>
<input type="text" id="msg">
<button id="send">发送</button>
<script>let channel = new BroadcastChannel('BroadcastChannel-test')send.onclick = function () {let msg = document.getElementById("msg").valuechannel.postMessage(msg)}</script>
</body>

pageB.html:

<body>
收到了消息:<span id="text"></span>
<script>let channel = new BroadcastChannel("BroadcastChannel-test")channel.addEventListener("message", function (e) {document.getElementById('text').innerText = e.data})</script>
</body>

参考文档:https://developer.mozilla.org/zh-CN/docs/Web/API/Broadcast_Channel_API


6.MessageChannel

创建一个新的消息通道,并通过它的两个MessagePort 属性发送数据。常见场景iframe通信。

pageA.html:

<body>
<input type="text" id="msg">
<button id="send">发送</button>
<p>收到iframe消息:<span id="text"></span></p>
<iframe src="pageB.html" width='640' height='320'></iframe>
<script>let iframe = document.querySelector('iframe');send.onclick = function () {let channel = new MessageChannel();channel.port1.onmessage = onMessagelet msg = document.getElementById("msg").valueiframe.contentWindow.postMessage(msg, '*', [channel.port2]);}function onMessage(e) {document.getElementById('text').innerHTML = e.data}</script>
</body>

pageB.html:

<body>
<input type="text" id="msg">
<button id="send">发送</button>
<p>收到main消息:<span id="text"></span></p>
<script>window.addEventListener('message', onMessage);let port = nullfunction onMessage(e) {document.getElementById('text').innerHTML = e.data;port = e.ports[0]}send.onclick = function () {let msg = document.getElementById("msg").valueif (port)port.postMessage(msg);}</script>
</body>

参考文档:https://developer.mozilla.org/zh-CN/docs/Web/API/MessageChannel


» 总结

窗口通信的方式有多种,大部分都是同源的,跨域通信可能要通过WebSocketiframe等来解决。另外有些还有浏览器兼容性的问题,使用时需谨慎。

如有问题,欢迎指出。

浏览器窗口通信的多种方式相关推荐

  1. 【Web技术】1091- 跨浏览器窗口 ,7种方式,你还知道几种呢?

    前言 为什么会扯到这个话题,最初是源于听 https://y.qq.com/ QQ音乐, 播放器处于单独的一个页面 当你在另外的一个页面搜索到你满意的歌曲的时候,点击播放或添加到播放队列 你会发现,播 ...

  2. Vue通信、传值的多种方式,详解

    Vue通信.传值的多种方式,详解 转自:https://blog.csdn.net/qq_35430000/article/details/79291287 一.通过路由带参数进行传值 ①两个组件 A ...

  3. android组建之间通信_android组件间通信有哪些方式

    四大组件以及通讯机制: activity (1)一个Activity通常就是一个单独的屏幕(窗口). (2)Activity之间通过Intent进行通信. (3)android应用中每一个Activi ...

  4. 手机端扣扣浏览器图片居中_实现图片始终居中显示于浏览器窗口中心位置

    盒模型 在敲代码之前,首先建立一个盒模型,这让写代码的时候变得思路清晰. 本案例中,所要实现的是图片居中显示,超出浏览器窗口部分的图片隐藏.因此,盒模型如图: 图片以浏览器窗口作为定位元素,居中显示. ...

  5. html中的父子通信代码,Vue.js 父子组件通信的十种方式

    面试官:Vue 中父子组件通信有哪些方式? 自己先想一分钟. 无可否认,现在无论大厂还是小厂都已经用上了 Vue.js 框架,简单易上手不说,教程详尽,社区活跃,第三方套件还多.真的是前端开发人员必备 ...

  6. html监听页面关闭事件,JS针对浏览器窗口关闭事件的监听方法集锦

    本文实例总结了JS针对浏览器窗口关闭事件的监听方法.分享给大家供大家参考,具体如下: 方式一:(适用于IE浏览器,而且刷新不提示,只在点击浏览器关闭按钮的时候提示) window.οnbefοreun ...

  7. Javascript 获取浏览器窗口中文档(视口)可用尺寸的方法

    摘要: 由于浏览器的差异,许多信息的获取都要考虑兼容性,窗口中文档可用尺寸是一个经常需要用到的信息,由于浏览器不同甚至版本不同,获取的方法也不一样,本文介绍的函数能够兼容各种浏览器,获取这一信息.同时 ...

  8. BOM 浏览器窗口尺寸 浏览器的弹出层 浏览器的地址栏 浏览器的历史记录 浏览器的版本信息 浏览器的常见事件 浏览器卷去的高度和宽度

    浏览器窗口尺寸 + 指的是浏览器可视窗口的尺寸 + 浏览器可能会出现滚动条=> 在一般浏览器中,滚动条算浏览器的一部分=> 在MAC中的safari浏览器上,是不算的 滚动条是隐形的 + ...

  9. android中资源文件的两种访问方式,在android开发中进行数据存储与访问的多种方式介绍...

    在android开发中进行数据存储与访问的多种方式介绍 更新时间:2013年06月07日 16:24:23   作者: 很多时候我们的软件需要对处理后的数据进行存储或再次访问,Android为数据存储 ...

  10. 利用对象存储多种方式 保障OSS数据安全

    本文介绍如何通过对象存储OSS提供的加密.访问控制.日志与监控及数据保护等多种方式来保障OSS的数据安全性. 加密 OSS提供服务器端加密.客户端加密以及数据传输加密三种数据加密方式. 服务器端加密 ...

最新文章

  1. 大数据文字游戏_基于大数据的游戏化教学系统研究.docx
  2. Invalid argument(s) 'pool_size' sent to create_engine(), using configuration
  3. POJ 3522 Slim Span (Kruskal枚举最小边)
  4. 作为大数据和云计算学习的一个序吧
  5. 无法全新安装_好墙板更需好安装:护墙板安装新方法
  6. 解决Qt5 Creator无法切换输入法(fcitx),Ubuntu中不能使用搜狗输入法录入汉字问题...
  7. 案例与案例之间的非常规排版
  8. .net 页面框架的层次问题,嵌套问题
  9. c++中queue用法
  10. sourceInsight4 破解笔记(完美破解)【转】
  11. Oracle查询时15分钟划分
  12. Flink 在快手实时多维分析场景的应用
  13. python绘制动态心电图_可穿戴设备中测心电图这样功能能达到医用标准吗?未来前景如何?在医用和便携之间是否还有市场?...
  14. ftp服务器和共享文件夹权限设置,ftp服务器共享文件夹权限设置
  15. android+ts+播放器,开源播放器ijkplayer的编译
  16. 华三服务器java挂载镜像_RAKsmart美国服务器实现挂载镜像操作过程
  17. python假期培训班
  18. 微信小程序实现地图导航功能
  19. 弱加密算法有哪几种_常见的几种加密方法
  20. 今日只为你狂欢-----JAVA线程总结(零基础入门)

热门文章

  1. Python爬取图片
  2. 二分算法:数的三次方根
  3. 使用Android Studio 创建第一个Android 应用
  4. 科学研究方法与论文写作-课后习题答案
  5. Python断言与isinstance()判断数据类型
  6. java如何实现识别图片上的文字
  7. html关于点击radio触发事件
  8. android 调用系统图片编辑,android 调用系统 裁剪 图片
  9. proc sys文件系统对比
  10. ant design vue 修改 table 的默认分页的pageSize