项目里面使用了wujie进行搭建的,在子项目中有一个iframe页面需要在父页面中进行数据获取以及展示。一开始打算使用wujie的bus来进行通信,后来发现iframe页面不会被wujieApp包裹,所以无法使用无界的相关API,所以只能使用原生的iframe来进行通信。算是个小小的记录吧。
项目实例:
父应用:
window.addEventListener('message', (event: MessageEvent) => {
console.log('iframe收到的event信息为:', event);
// 一般都会判断一下来源 防止恶意攻击
const { origin } = event;
if (origin.indexOf('xxx') === -1) {
return;
}
...do something
});
子应用:
const data = {
loadType:'iframe',
title: '新页签',
url: `http://dev.com/dispatch/#${url}`
};
// 给父应用发送消息 *是不指定具体的地址
window.parent.postMessage(data,'*')
具体通信方式:
父应用监控子应用:
window.addEventListener('message',(event) => {...})
父应用给子应用传值:
var iframeDom = document.getElementById('testIframe');
var data = 'hello, child!';
iframeDom.contentWindow.postMessage(data,'*'/url)
子应用监控父应用传值:
window.addEventListener('message', e => {
// 通过origin对消息进行过滤,避免遭到XSS攻击
if (e.origin === 'http://127.0.0.1:8001') {
console.log('父页面传输过来参数', e.data);
... do something
}
});
子应用给父应用传值:
let data = {
from: 'iframe child page',
code: 200,
data: '子页面主动触发通讯'
};
window.parent.postMessage(data, '*');
// 这种只能在同源下才可以,如果不是则获取不到外层页面的信息
// window.parent // 获取父页面window对象,如果没有父页面将返回自身
// window.top // 获取顶层页面window对象
postMessage方法:
postMessage 的发送与接收,Window.postMessage 是 HTML5 提供的一个跨域解决方案。
在HTML5标准引入的window对象下的postMessage方法,可以允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。
- 父页面像子页面通信:ifram的contentWindow.postMessage
- 子页面像父页面通信:window.parent.postMessage或window.top
- 接收的话直接window监听onmessage事件即可
otherWindow.postMessage(message, targetOrigin, [transfer]);
其中的参数:
otherWindow
目标窗口。比如 iframe 的 contentWindow 属性
message
将要发送到其他 窗口 的数据。
targetOrigin
目标窗口的域。其值可以是字符串"*"(表示无限制)或者一个 URI。不提供确切的 targetOrigin 将导致数据泄露到任何对数据感兴趣的恶意站点。