我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

BroadcastChannel翻译成中文就是广播频道,从这个角度上来考虑的话,就很容易理解本文中的主要内容了。首先,所有的频道参与者都必须有关系,是同一个域名下。其次,可以发送数据,也可以接受数据。另外,这个是基于前端的数据通信概念,暂时无关后端。所以,参与通信的所有页面,也都是基于同一个电脑上面的同一个浏览器的不同页面的概念。意思就是说,是一种同一个设备上的不同页面之间的通讯手段。

苏南大叔:BroadcastChannel如何解决同域下不同页面通信技术难题? - broadcast-channel
BroadcastChannel如何解决同域下不同页面通信技术难题?(图2-1)

大家好,这里是苏南大叔的平行空间笔记本博客,这里记录苏南大叔的代码所想。如果您喜欢苏南大叔写的内容,欢迎转发链接。本文描述js页面间通信技术中的一个可能的实现方式:BroadcastChannel。测试环境是:谷歌浏览器@110.0.5481.77。(苏南大叔认为:这个BroadcastChannel代码使用起来就很像是个单机版的socket.io代码)。

定义频道

在多个相关页面里面,定义下面类似的代码。重点是:所有的广播的名字需要保持一致。范例代码如下:

var _channel = new BroadcastChannel("sunan");

发送消息

确保相关页面代码中,连接的是同一个频道后。下一个步骤就是在其中某个页面上发送数据。范例代码如下:

_channel.postMessage({
  msg:"苏南大叔发送的消息",
  coin:5
});

接收消息

一般来说,就是在另外一个页面上来接收相关的消息了。范例代码如下:

_channel.onmessage=function(ev){
  console.log(ev.data.msg);
  console.log(ev.data.coin);
};

这里大家可以看到,消息被包装成了事件evdata。而data里面是个对象,对象的key是自己可以自定义的。
由于.on.addEventListener是类似写法的关系,上边的例子,还可以写成:

_channel.addEventListener("message",function(ev){
  console.log(ev.data.msg);
  console.log(ev.data.coin);
};
值得特别说明的是:在本例中,.on.addEventListener这两种写法,是可以共存的。两者并不会产生覆盖关系。

断开链接

new BroadcastChannel的时候,就已经开始建立链接了。所以,在适当的时机来断开频道链接,也是很有必要的。范例代码如下:

_channel.close();

当频道关闭后,再次试图发送消息,会得到如下类似的错误信息:

Uncaught DOMException: Failed to execute 'postMessage' on 'BroadcastChannel': Channel is closed
官方还有个.onmessageerror(err)的用法,不过用来捕获的错误类型是消息不能格式化的错误信息,似乎没有啥用。参考文档:
https://developer.mozilla.org/zh-CN/docs/Web/API/BroadcastChannel/messageerror_event

测试代码

页面一:

<script>
  var _channel = new BroadcastChannel("sunan");
  _channel.onmessage = function (ev) {
    console.log(ev);
    console.log(ev.data.msg);
    console.log(ev.data.coin);
    _channel.postMessage({
      msg: `执行内容 : ${ev.data.msg},${ev.data.coin}`,
    });
  };
</script>

页面二:

<button id="_btn">点击发送消息</button>
<button id="_btn2">断开链接</button>
<script>
  var _channel = new BroadcastChannel("sunan");
  _btn.onclick = function () {
    _channel.postMessage({
      msg: "苏南大叔",
      coin: 888,
    });
  };
  _channel.onmessage = function (ev) {
    console.log(ev.data.msg);
  };
  _btn2.onclick = function () {
    _channel.close(function(){
        console.log("close")
    });
  };
</script>

这个例子中,第二个页面发送消息后,会被第一个页面接收并执行,然后返回处理结果到第二个页面。

苏南大叔:BroadcastChannel如何解决同域下不同页面通信技术难题? - 页面执行顺序
BroadcastChannel如何解决同域下不同页面通信技术难题?(图2-2)

  • 这个的相关BroadcastChannel测试页面,原生支持file://协议。就是说,本地文件直接双击打开就可以测试了,这对于在类似的技术规范中,可以说是非常宽松了。
  • 另外,两个页面独立打开即可,并不存在iframe关系。
  • 两个页面必须在同一个域下面(都是file://的话,算一个域)。一个直接双击,另外一个通过链接访问的话,这都不算同域。

相关链接

总结

以前讲过很多页面间通信的文章,本文中描述的通信技术BroadcastChannel,虽然不能解决跨域通信的问题,但是,也是一个不错的同域同设备上不同页面间的数据通信的手段。但是,部分老浏览器是不兼容的这个BroadcastChannel技术的。这个并不是本文考虑的范畴之内。

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   js