文章目录
1.BroadcastChannel
在前端,我们经常会用postMessage
来实现页面间的通信,但这种方式更像是点对点的通信。对于一些需要广播(让所有页面知道)的消息,用postMessage
不是非常自然。Broadcast Channel
就是用来弥补这个缺陷的。
BroadcastChannel
会创建一个所有同源页面
都可以共享
的(广播)频道,因此其中某一个页面发送的消息可以被其他页面监听到。
BroadcastChannel
需要注意浏览器兼容性。
1.1 使用构造函数创建一个实例
const bc = new BroadcastChannel('BroadcastChannel1');
可以接受一个DOMString
作为 name
,用以标识这个 channel
。在其他页面,可以通过传入相同的 name
来使用同一个广播频道。
该 name
值可以通过实例的.name
属性获得
console.log(bc.name);
1.2 监听消息
BroadcastChannel
创建完成后,就可以在页面监听广播的消息:
bc.onmessage = function(e) {
console.log('receive:', e.data);
};
对于错误也可以绑定监听:
bc.onmessageerror = function(e) {
console.warn('error:', e);
};
除了为.onmessage
赋值这种方式,也可以使用addEventListener
来添加message
监听。
window.addEventListener('message', function(event) {
if (event.origin !== 'https://example.com') return; // 验证消息来源
console.log('Received message from first window:', event.data);
}, false)
1.3 发送消息
BroadcastChannel
实例也有一个对应的postMessage
用于发送消息:
bc.postMessage('hello')
1.4 关闭
bc.close();
2 window.postMessage
window.postMessage
是一种 JavaScript 方法,用于在窗口之间发送消息。它允许不同源的窗口之间进行通信
2.1 发起通信
方法的第一个参数是发送的消息,无格式要求;第二个参数是域名限制,当不限制域名时填写*
// 第一个窗口
var targetWindow = window.open('https://example.com', '_blank');
targetWindow.postMessage('Hello from first window!', '*');
2.2 监听通信
// 监听message事件,如果有监听到消息内容就执行以下内容
window.addEventListener("message", (e) => {
// 判断是否同源
if (e.origin === location.origin) {
// 接收到的消息是否为约定好的唯一标识
if(e.data === "updateList") {
// 刷新列表操作
...
}
}
});
2.3 iframe中实现父子窗口通信
<iframe id="proxy" class="myIframe" src="http://localhost:8089/pp/app/aa/bbbbb.html" ></iframe>
父页面向子页面发送消息
const iframe = document.getElementId('proxy')
iframe.contentWindow.postMessage({oldPhoto: '我的照片'}, "*");
子页面接收父页面发送的消息
window.onmessage = function(event){
console.log(event.data.oldPhoto) // 我的照片
}
子页面向父页面传递消息
window.parent.postMessage({info: '再给我发一张'}, "*");
父页面接收子页面传递的消息
window.onmessage = function(event){
console.log(event.data.info) // 再给我发一张
}
3. 总结
Broadcast Channel
与window.postMessage
都能进行跨页面通信Broadcast Channel
只能用于同源
页面之间进行通信,而window.postMessage
可以任何页面之间通信- 基于
Broadcast Channe
l 的同源策略,它无法完成跨域的数据传输;跨域的情况,我们只能使用window.postMessage
来处理 Broadcast Channel
更加安全,一般推荐使用Broadcast Channel
来进行跨页面通信