示例地址

prologue

  • 之前在网上看到一个面试题:如何实现浏览器中多个标签页之间的通信。我目前想到的方法有三种:使用websocket协议、通过localstorage、以及使用html5浏览器的新特性SharedWorker。
  • websocket这里先不介绍了,全双工(full-duplex)通信自然可以实现多个标签页之间的通信,相信网上通过websocket实现聊天室的教程也不少,我自己也用socket.io写了一个在线聊天室
  • 接下来会介绍另外两个方法:监听localstorage和使用SharedWorker

localstorage

  • localstorage是浏览器多个标签共用的存储空间,所以可以用来实现多标签之间的通信(ps:session是会话级的存储空间,每个标签页都是单独的)。
  • 直接在window对象上添加监听即可:
window.onstorage = (e) => {console.log(e)}
// 或者这样
window.addEventListener('storage', (e) => console.log(e))
  • onstorage以及storage事件,针对都是非当前页面对localStorage进行修改时才会触发,当前页面修改localStorage不会触发监听函数。然后就是在对原有的数据的值进行修改时才会触发,比如原本已经有一个key会a值为b的localStorage,你再执行:localStorage.setItem('a', 'b')代码,同样是不会触发监听函数的。

webworker

  • 我们都知道JavaScript是单线程的,但是浏览器是拥有过个线程的比如:gui渲染线程、JS引擎线程、事件触发线程、异步http请求线程。
  • webworker作为浏览器的一个新特性,可以提供一个额外的线程来执行一些js代码,并且不会影响到浏览器用户界面。
  • 应用场景:比如页面中包含耗时较大的算法代码时,就会阻塞线程影响浏览器渲染等等。这时候就可把耗时代码,放到webworker(另一个线程)中执行。
  • 注意,这种多线程能力不是JavaScript语言原生具有的,而是浏览器宿主环境提供的。
  • 普通的webworker直接使用new Worker()即可创建,这种webworker是当前页面专有的。然后还有种共享worker(SharedWorker),这种是可以多个标签页、iframe共同使用的,接下来介绍如何使用SharedWorker实现标签页之间的通信。

SharedWorker

  • SharedWorker可以被多个window共同使用,但必须保证这些标签页都是同源的(相同的协议,主机和端口号)
  • 首先新建一个js文件worker.js,具体代码如下:
// sharedWorker所要用到的js文件,不必打包到项目中,直接放到服务器即可
let data = ''
onconnect = function (e) {let port = e.ports[0]port.onmessage = function (e) {if (e.data === 'get') {port.postMessage(data)} else {data = e.data}}
}
  • webworker端(暂且这样称呼)的代码就如上,只需注册一个onmessage监听信息的事件,客户端(即使用sharedWorker的标签页)发送message时就会触发。

  • 注意webworker无法在本地使用,出于浏览器本身的安全机制,所以我这次的示例也是放在服务器上的,worker.jsindex.html在同一目录。

  • 因为客户端和webworker端的通信不像websocket那样是全双工的,所以客户端发送数据和接收数据要分成两步来处理。示例中会有两个按钮,分别对应的向sharedWorker发送数据的请求以及获取数据的请求,但他们本质上都是相同的事件--发送消息。

  • webworker端会进行判断,传递的数据为'get'时,就把变量data的值回传给客户端,其他情况,则把客户端传递过来的数据存储到data变量中。下面是客户端的代码:

// 这段代码是必须的,打开页面后注册SharedWorker,显示指定worker.port.start()方法建立与worker间的连接if (typeof Worker === "undefined") {alert('当前浏览器不支持webworker')} else {let worker = new SharedWorker('worker.js')worker.port.addEventListener('message', (e) => {console.log('来自worker的数据:', e.data)}, false)worker.port.start()window.worker = worker}
// 获取和发送消息都是调用postMessage方法,我这里约定的是传递'get'表示获取数据。
window.worker.port.postMessage('get')
window.worker.port.postMessage('发送信息给worker')
  • 页面A发送数据给worker,然后打开页面B,调用window.worker.port.postMessage('get'),即可收到页面A发送给worker的数据。
  • 参考:developer.mozilla.org/zh-CN/docs/…

实现多个标签页之间通信的几种方法相关推荐

  1. [html] 浏览器内多个标签页之间的通信方式有哪些?

    [html] 浏览器内多个标签页之间的通信方式有哪些? 个人简介 我是歌谣,欢迎和大家一起交流前后端知识.放弃很容易, 但坚持一定很酷.欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题

  2. 线程间通信的三种方法 (转)

    http://www.cnblogs.com/puxidun/archive/2009/12/06/1618142.html 线程间通信的三种方法 多线程通信的方法主要有以下三种:  1.全局变量 进 ...

  3. Linux下进程通信的八种方法

    Linux下进程通信的八种方法:管道(pipe),命名管道(FIFO),内存映射(mapped memeory),消息队列(message queue),共享内存(shared memory),信号量 ...

  4. 浅议C#客户端和服务端通信的几种方法:Rest和GRPC和其他

    本文来自:https://michaelscodingspot.com/rest-vs-grpc-for-asp-net/ 浅议C#客户端和服务端通信的几种方法:Rest和GRPC 在C#客户端和C# ...

  5. vue组件通信的几种方法

    vue中我们最常使用的就是父子之间的通信还有全局数据管理vuex了,下面粗略说一下vue组件通信的几种方法 组件通信的几种方式 1.父子组件通信 2.兄弟组件通信 3.跨多层级组件通信 4.任意组件( ...

  6. android fragment传递参数_fragment之间传值的两种方法

    在Activity中加载Fragment的时候.有时候要使用多个Fragment切换.并传值到另外一个Fragment.也就是说两个Fragment之间进行参数的传递.查了很多资料.找到两种方法.一种 ...

  7. html设置word页边距,word怎样设置页边距的两种方法

    有些时候,我们需要设置一下word文档的页边距,来增添文字输入空间和获得一个较好的布局,那么怎么来设置呢?那么下面就由学习啦小编给大家分享下word设置页边距的技巧,希望能帮助到您. word设置页边 ...

  8. Vue组件之间传值的几种方法 (直接上代码)

    vue组件之间传值的几种方法总结 一. props(父传子) 父组件 传递 <template><div><HelloWorld :msg="msg" ...

  9. 浏览器内多个标签页之间的通信方式有哪些?

    传递方式 1.WebSocket (可跨域) WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议. 2.postMessage(可跨域) window.pos ...

最新文章

  1. 在eclipse中通过基于spring data的easyrest风格的maven项目操纵cassandra和lucene
  2. web页面 float定位导致“溢出现象”处理
  3. eventbus使用_Android EventBus框架的使用介绍
  4. Nginx 配置TCP负载均衡
  5. 开源医学图像处理平台NiftyNet简介
  6. HBase 1.3(NOSQL) 发布,性能大幅提升
  7. html5调用系统声音1s响一次_为你的html5网页添加音效示例
  8. h5居中loading_H5样式与布局 --常用居中方法
  9. 钉钉直播html,钉钉直播功能介绍,钉钉直播步骤详情
  10. c语言求函数的极限例题,第二讲--函数的极限典型例题.doc
  11. postgresql立式版本下载_【PostgreSQL下载】PostgreSQL官方版下载_多特软件站
  12. 量化投资学习——经济周期
  13. CTF逆向-IDA Pro攻防世界Hello CTF
  14. 为什么选择golang
  15. 【GANs学习笔记】(二)GANs大家族分类
  16. 推荐一些有趣的编程书籍和电影
  17. 用Kali实现局域网内ARP欺骗和中间人攻击
  18. 手机黑屏微信连接不上服务器,华为手机黑屏收不到微信?“老司机”竟然是这么做的!...
  19. 考研计算机四门专业课,大家一起来呀,计算机考研四门专业课程中哪一门最难?...
  20. 【vue系列-01】vue初级入门以及demo实现详解

热门文章

  1. GAN 为什么需要如此多的噪声?
  2. AI时代,摄影艺术即将消失?
  3. 2019年上半年收集到的人工智能机器学习方向干货文章
  4. 「AI初识境」深度学习模型中的Normalization,你懂了多少?
  5. AI系列一:机器学习介绍
  6. 【综述专栏】自动驾驶中可解释AI的综述和未来研究方向
  7. 实现AGI,强化学习就够了?Sutton、Silver师徒联手:奖励机制足够实现各种目标...
  8. RISC-V会被卡吗?那么你觉得C语言会不会被卡? | 包云岗
  9. Nature:新聘“诺奖级泰斗”研究揭示大脑中执行不同认知功能环路之间的协同作用
  10. 《EE Times》评出2020年全球最值得关注的18家传感器公司