效果图.gif

prologue

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

     
    image
  • 因为客户端和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')

实现多个标签页之间通信的几种方法(sharedworker)的更多相关文章

  1. 浏览器内多个标签页之间的通信之storage

    在一个标签页里面使用 localStorage.setItem(key,value)添加(修改.删除)内容: 在另一个标签页里面监听 storage 事件. 即可得到 localstorge 存储的值 ...

  2. 利用cookie实现浏览器中多个标签页之间的通信

    原理: cookie是浏览器端的存储容器,而且它是多页面共享的,利用cookie多页面共享的特性,可以实现多个标签页的通信. 比如: 一个标签页发送消息(将发送的消息设置到cookie中),一个标签页 ...

  3. 利用localStorage实现浏览器中多个标签页之间的通信

    原理: localStorage是浏览器存储数据的容器,而且它是多页面共享的,利用localStorage多页面共享的特性,可以实现多个标签页的通信. 比如: 一个标签页发送消息(将发送的消息设置到l ...

  4. sessionStorage 的数据会在同一网站的多个标签页之间共享吗?这取决于标签页如何打开

    一直以来,我所以为的 sessionStorage 的生命周期是这样的:在 sessionStorage 中存储的数据会在当前浏览器的同一网站的多个标签页中共享,并在此网站的最后一个标签页被关闭后清除 ...

  5. IPC进程之间通信的几种方式

    概念 进程间通信就是在不同进程之间传播或交换信息,那么不同进程之间存在着什么双方都可以访问的介质呢?进程的用户空间是互相独立的,一般而言是不能互相访问的,唯一的例外是 共享内存区 .但是,系统空间却是 ...

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

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

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

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

  8. vue-learning:31 - component - 组件间通信的6种方法

    vue组件间通信的6种方法 父子组件通信 prop / $emit 嵌套组件 $attrs / $liteners 后代组件通信 provide / inject 组件实例引用 $root / $pa ...

  9. c#中实现串口通信的几种方法

    c#中实现串口通信的几种方法 通常,在C#中实现串口通信,我们有四种方法: 第一:通过MSCOMM控件这是最简单的,最方便的方法.可功能上很难做到控制自如,同时这个控件并不是系统本身所带,所以还得注册 ...

随机推荐

  1. js 实现动态时间

    <span id="timebox"></span>                   //承载时间的span $(function () { var o ...

  2. LeetCode算法题-Ugly Number(Java实现-四种解法)

    这是悦乐书的第199次更新,第208篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第64题(顺位题号是263).编写一个程序来检查给定的数字是否是一个丑陋的数字.丑陋的数 ...

  3. iOS弹出UIViewController小视图

    在TestViewController1中弹出TestViewController2 在TestViewController中点击按钮或者什么触发方法里面写入以下代码 TestViewControll ...

  4. Java strictfp

    strictfp关键字 用于强制Java中的浮点计算(float或double)的精度符合IEEE 754标准. 不使用strictfp:浮点精度取决于目标平台的硬件,即CPU的浮点处理能力. 使用s ...

  5. 我的BRF+自学教程(二):跟踪模式(trace mode)

    使用自开发程序来处理业务逻辑时,处理过程通常是个黑箱,业务顾问和业务用户不知道程序的具体运行方式,要依赖文档和频繁的沟通来确认实际情况. BRFplus可以通过配置的方式实现业务逻辑,使得业务人员把业 ...

  6. Java程序设计教程(第2版)阅读总结

    为了重新拣起对Java的回忆,只好又找了本基础书.由于成都高新图书馆的计算机书实在不多,只能找到这本了.简单读了下Java部分,总结如下: 优点:虽然本书也是作者编的而不是作者著的,但是可以看出作者编 ...

  7. 强大的Notepad++,竟然还是自由使用的

    这么好用的工具,竟然还是可以自由使用的的,当然就不用去找某些软件的破解版了. 除了本身很好用,还有插件功能,插件许多也是自由使用的,利用插件就可以实现程序员需要的一个手工编辑器了.

  8. 第一次使用Open Live Writer维护BlogJava

    换了电脑,又重装了一堆东西,现在才把Open Live Writer整好.顺便记下几个心得: Open Live Writer已经没办法从网站上下载了,介绍个方法,可以把地址直接拷贝到迅雷里面,然后请 ...

  9. Python的datetime模块分析

    datetime模块用于是date和time模块的合集,datetime有两个常量,MAXYEAR和MINYEAR,分别是9999和1. datetime模块定义了5个类,分别是 1.datetime ...

  10. 一、tars简单介绍 二、tars 安装部署资料准备

    1.github地址https://github.com/Tencent/Tars/ 2.tars是RPC开发框架,目前支持c++,java,nodejs,php 3.tars 在腾讯内部已经使用了快 ...