BroadcastChannel如何解决同域下不同页面通信技术难题?
发布于 作者:苏南大叔 来源:程序如此灵动~BroadcastChannel
翻译成中文就是广播频道,从这个角度上来考虑的话,就很容易理解本文中的主要内容了。首先,所有的频道参与者都必须有关系,是同一个域名下。其次,可以发送数据,也可以接受数据。另外,这个是基于前端的数据通信概念,暂时无关后端。所以,参与通信的所有页面,也都是基于同一个电脑上面的同一个浏览器的不同页面的概念。意思就是说,是一种同一个设备上的不同页面之间的通讯手段。
大家好,这里是苏南大叔的程序如此灵动博客,这里记录苏南大叔的代码所想。如果您喜欢苏南大叔写的内容,欢迎转发链接。本文描述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);
};
这里大家可以看到,消息被包装成了事件ev
的data
。而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
测试页面,原生支持file://
协议。就是说,本地文件直接双击打开就可以测试了,这对于在类似的技术规范中,可以说是非常宽松了。 - 另外,两个页面独立打开即可,并不存在
iframe
关系。 - 两个页面必须在同一个域下面(都是
file://
的话,算一个域)。一个直接双击,另外一个通过链接访问的话,这都不算同域。
相关链接
- https://newsn.net/say/script-crossorigin.html
- https://newsn.net/say/window-name-msg.html
- https://newsn.net/say/cors-jsonp.html
总结
以前讲过很多页面间通信的文章,本文中描述的通信技术BroadcastChannel
,虽然不能解决跨域通信的问题,但是,也是一个不错的同域同设备上不同页面间的数据通信的手段。但是,部分老浏览器是不兼容的这个BroadcastChannel
技术的。这个并不是本文考虑的范畴之内。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。