浏览器多标签页通信

面试官:加入我在另外一个tab页打开了你这个购物页面,然后我在其中一个页面点击了添加购物车,我在另一个页面怎么同步得到购物车信息
不清楚要点的小傻兔:点击添加购物车按钮后前端在原来的购物车数据之上加上新添加的商品,然后发送请求将添加的商品发送给后端添加到购物表中实现后台数据的同步。
面试官:有没有一种可能不同tab之间是不会同时触发时间,你这个页面的前端数据修改了但是另一个tab的还是没有改
清楚要点的小傻兔:啊。。这。。,问的不同tab之间的通信呀。。。。(不会.jpg)

来吧,上答案!

1.localStorage实现通信(监听localStorage变化)
localStorage的特点:
同域共享存储空间
持久化将数据存储来浏览器
提供事件监听localStorage变化

注意点:
pageA和pageB同源,即域名、端口、协议等都是相同的。
使用storage事件监听localStorage变化

// pageA.html
<body>
  <h1>pageA</h1>
</body>
<script>
  window.addEventListener("storage", (e) => {
    console.info("localStorage发生变化:", e)
  })
</script>

// pageB.html
<body>
  <h1>pageB</h1>
  <button id="btnB">添加数据到localStorage</button>
</body>
<script>
  let btnB = document.getElementById("btnB");
  let num = 0;
  btnB.addEventListener("click", () => {
    localStorage.setItem("num", num++)
  })
</script>

2.使用websocket
websocket是一种网络通讯协议。我们都知道在使用HTTP协议的时候,我们与服务端都是通过发请求的方式进行通讯的,而且这种通讯只能由客户端发起。websocket协议就弥补了这一缺点,它是一个全双工通信的协议,意味着客户端和服务端可以互相通信,享受平等关系。
最简单列子就是聊天室,我们在聊天室里面可以收消息,也可以发消息,只要我们与服务端通过websocket建立好了连接。

websocket特点:
保持连接状态,HTTP协议是无状态连接,即请求完毕后就会关闭连接。
全双工通信,客户端和服务端平等对待,可以互相通信。
建立在TCP协议之上
没有同源共享策略,即可实现跨域共享

代码演示:
我们先来搭建一个简单的websocket服务器,用于pageA和pageB的连接,新建index.js文件。
初始化命令:

npm init -y
npm install --save ws
//运行命令:node index.js
// index.js
let WebSocketServer = require("ws").Server;
let wss = new WebSocketServer({ port: 3000 });

// 创建保存所有已连接到服务器的客户端对象的数组
let clients = [];

// 为服务器添加connection事件监听,当有客户端连接到服务端时,立刻将客户端对象保存进数组中。
wss.on("connection", function (client) {
  console.log("一个客户端连接到服务器");
  if (clients.indexOf(client) === -1) {
    clients.push(client);
    // 接收客户端发送的消息
    client.on("message", function (msg) {
      console.log("收到消息:" + msg);
      // 将消息发送给非自己的客户端
      for (let key of clients) {
        if (key != client) {
          key.send(msg.toString());
        }
      }
    });
  }
});
// pageA
<script>
  // 创建一个websocket连接
  var ws = new WebSocket('ws://localhost:3000/');
  // WebSocket连接成功回调
  ws.onopen = function () {
    console.log("websocket连接成功")
  }
  // 这里接受服务器端发过来的消息
  ws.onmessage = function (e) {
    console.log("服务端发送的消息", e.data)
  }
</script>
//pageB
<script>
  let btnB = document.getElementById("btnB");
  let num = 0;
  btnB.addEventListener("click", () => {
    ws.send(`客户端B发送的消息:${num++}`);
  })
  // 创建一个websocket连接
  var ws = new WebSocket('ws://localhost:3000/');
  // WebSocket连接成功回调
  ws.onopen = function () {
    console.log("websocket连接成功")
  }
</script>

当我们点击pageB中的按钮时,会通过websocket向服务端发送一条消息,服务端接收到这条消息之后,会将消息转发给pageA,这样pageA就得到了pageB传来的数据。
总体来说,原理很简单,只是需要了解websocket。通常情况下,我们不建议使用websocket来进行多标签页通信,因为这回增加服务器的负担。

3.SharedWorker
sharedWorker就是webWorker中的一种,它可以由所有同源页面共享,利用这个特性,我们就可以使用它来进行多标签页之前的通信。

sharedWorker特点:
跨域不共享,即多个标签页不能跨域
使用port发送和接收消息
如果url相同,且是同一个js,那么只会创建一个sharedWorker,多个页面共享这个sharedWorker

其实它和我们的webSocket实现多页面通讯的原理很类似,都是发送数据和接收数据这样的步骤,shardWorker就好比我们的webSocket服务器。

// worker.js
const set = new Set()
onconnect = event => {
  const port = event.ports[0]
  set.add(port)
  // 接收信息
  port.onmessage = e => {
    // 广播信息
    set.forEach(p => {
      p.postMessage(e.data)
    })
  }
  // 发送信息
  port.postMessage("worker广播信息")
}
//pageA
<script>
  const worker = new SharedWorker('./worker.js')
  worker.port.onmessage = e => {
    console.info("pageA收到消息", e.data)
  }
</script>
//pageB
<script>
  const worker = new SharedWorker('./worker.js')
  let btnB = document.getElementById("btnB");
  let num = 0;
  btnB.addEventListener("click", () => {
    worker.port.postMessage(`客户端B发送的消息:${num++}`)
  })
</script>

sharedWorker的原理和websocket有点类似,都是广播和接收的原理,但是它也有一些缺点,比如调试不太方便、兼容性不太好。所以使用的时候一定要结合实际情况使用。

4.使用cookie + setInterval(轮询)
cookie特点:
跨域不共享
具有存储空间限制
请求会自动携带cookie

//pageA
<script>
  setInterval(() => {
    //加入定时器,让函数每一秒就调用一次,实现页面刷新
    console.log("cookie",document.cookie)
  }, 1000);
</script>
//pageB
<script>
  let btnB = document.getElementById("btnB");
  let num = 0;
  btnB.addEventListener("click", () => {
    document.cookie = `客户端B发送的消息:${num++}`
  })
</script>

这种方式实现的原理非常简单,就是在需要接收消息的页面不断轮询去查询cookie,然后发送消息的页面将数据存储在cookie中,这样就实现了简单的数据共享。
在这里插入图片描述

更多情况下的tab通信

详细使用

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值