介绍
- BroadcastChannel:提供了一种简单的跨页面通信方式,即可以在同一个页面中的不同 iframe,也可以在不同的页面之间进行通信。最重要的是只能在同源页面之间进行通信
- 若一个页面创建多个相同名称的通道,他们之间不会通信
- 关闭通道前,请确认消息已经接收完成,否则会导致信息丢失
- postMessage:可以在同一域名下的不同窗口或 iframe 之间进行通信,也可以在不同域名下的窗口或 iframe 之间进行跨域通信
- 需要确保消息接收方窗口的源地址是可信的,并且只接受预期的消息类型和格式
- 如果发送方和接收方在同一页面中,可以通过
window.postMessage()
方法来进行通信
使用
const channel = new BroadcastChannel('channel-name');
channel.postMessage(message: any);
channel.addEventListener('message', ({data: any}) => {
console.log(data);
})
channel.addEventListener('messageerror', e) => {
console.error(e);
})
channel.close();
- postMessage
const message = {...};
const targetOrigin = 'https://xxx.com';
window.parent.postMessage(message, targetOrigin);
window.addEventListener('message', event => {
if (event.origin !== 'https://example.com') {
return;
}
const message = event.data;
...
});
安全性
- 使用
postMessage
进行跨域通信需要注意安全性问题
- 消息源:通过
event.origin
验证消息源 - 内容:通过定义消息格式和类型限制消息内容
- XSS:对消息进行转义
- XSRF:使用
CSRF Token
,或检查Referer
- Dos:限制消息和频率的大小
实例
- 由于项目中是在同一个网站不同页面间传递数据,故这里使用
BroadcastChannel
- 发送
this.channel = new BroadcastChannel('my-channel')
this.channel.postMessage({
...
uuid: this.$route.query.uuid,
})
this.channel = new BroadcastChannel('my-channel')
this.channel.addEventListener('message', (e) => {
if (e.data.uuid === this.uuid) {
...
}
})