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

实现多个标签页之间的通信,本质上都是通过中介者模式来实现的。因为标签页之间没有办法直接通信,因此我们可以找一个中介者,让标签页和中介者进行通信,然后让这个中介者来进行消息的转发。

Plan 1.  LocalStorage 

原理:localStorage中支持监听storage变化时的事件,并且只有在不同标签页面且同源网页的时候才会触发。

实现方式:正常使用localstorage,在需要监听的位置写上如下代码:

 window.addEventListener("storage", (e) => {
    console.info("localStorage发生变化:", e)
  })
Plan 2.  PostMessage 

优点:可以安全地实现跨源通信。

实现方式:【postMessage 菜鸟

  • 发送
  var receiver = document.getElementById('receiver').contentWindow;
  var btn = document.getElementById('sendMessage');
  btn.addEventListener('click', function (e) {
      e.preventDefault();
      let val = 'Hello'
      receiver.postMessage(val, "http://example.org:8080");
  });
  • 接收
window.addEventListener("message", receiveMessage, false);

function receiveMessage(event) {
  // For Chrome, the origin property is in the event.originalEvent
  let origin = event.origin || event.originalEvent.origin;
  
  //示例,这里是发送方的url
  let url = 'http://example.org:8080' 

  if (origin !== url) return;

  // ...
}

小Tips: chrome浏览器中,URL 的窗口的消息的 targetOrigin 参数当前被错误解释,使得将导致发送消息的唯一值为 "*"。由于此值是不安全的,当目标窗口可以导航到其他地方的恶意网站,建议 postMessage 不用于与 chrome。

Plan 3.  ShareWorker 

原理:shareWorker 会在页面存在的生命周期内创建一个唯一的线程,并且开启多个页面也只会使用同一个线程。这个时候共享线程就可以充当中介者的角色,由所有同源页面共享,然后通过这个共享的线程来实现数据的交换。

实现方式:

        1) 新建worker.js

// 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广播信息")
}

        2) page1

<script>
  const worker = new SharedWorker('./worker.js')
  worker.port.onmessage = e => {
    console.info("page1收到消息", e.data)
  }
</script>

        3) page2

<script>
  const worker = new SharedWorker('./worker.js')
  let myBtn= document.getElementById("myBtn");
  let num = 0;
  myBtn.addEventListener("click", () => {
    worker.port.postMessage(`page2发送的消息:${num++}`)
  })
</script>

兼容性:【SharedWorker MDN

未完待续...

  • 14
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值