window.postMessage() 方法可以安全地实现跨源通信。通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为https),端口号(443为https的默认值),以及主机 (两个页面的模数 Document.domain设置为相同的值) 时,这两个脚本才能相互通信。window.postMessage() 方法提供了一种受控机制来规避此限制,只要正确的使用,这种方法就很安全。
以上摘自MDN 原文 postMessage;
背景:
应项目需求,需求对两个项目进行相互通信。A应用调用B应用里的某些页面,B应用发送消息给到A应用,想到了使用iframe 中的postMessage,最主要的是postMessage支持跨域使用,因此也避免了很多使用上的问题
例子
我这边使用的是react,所以就暂且用react来写例子了
子传父
父应用使用iframe前套子应用
import React, { useEffect } from 'react';
const Index = () => {
useEffect(()=>{
window.addEventListener('message',function(event){
if(event.data=='close'){
console.log('获取到子应用传递过来的值')
console.log(event)
}
})
},[])
return (
<div>
<iframe src="http://10.1.38.13:8001" width={800} height={800}></iframe>
</div>
);
};
export default Index;
子应用被嵌套后传递值到父应用
import styles from './index.less';
import { Button } from 'antd';
export default function IndexPage() {
const fnNs = ()=>{
window.parent.postMessage('close','*');
}
return (
<div>
<h1 className={styles.title}>Page index 我是子应用 哈哈哈哈</h1>
<Button onClick={fnNs}>子传父</Button>
</div>
);
}
父传子
父应用通过iframe嵌套子应用,并传递数据到子应用
import React, { useEffect } from "react";
const Index = ()=>{
useEffect(()=>{
createIframe('http://10.1.38.13:8001', 'calculation');
},[]);
/**
* 创建iframe
* @param src 子应用地址
* @param element 希望在某个元素上添加
*/
const createIframe = (src:string, element:string)=>{
// 在此元素上添加iframe
const childFrameObj:any = document.getElementById(element);
const iframe:any = document.createElement("iframe");
iframe.src = src;
childFrameObj.appendChild(iframe);
// 判断iframe是否加载完成
if (iframe.attachEvent){
iframe.attachEvent("onload", ()=>{
iframe.contentWindow.postMessage('啦啦啦 传值给子应用呀', '*');
});
} else {
iframe.onload = ()=>{
iframe.contentWindow.postMessage('啦啦啦 传值给子应用呀', '*');
};
}
}
return (
<div id='calculation'>
</div>
)
}
export default Index;
子应用被访问,并接收父应用传递过来的值
import React, { useEffect } from 'react';
import styles from './index.less';
export default function IndexPage() {
useEffect(()=>{
window.addEventListener('message',function(event){
console.log('--------获取被父应该调用后传递过来的值---------')
console.log(event.data)
})
},[])
return (
<div>
<h1 className={styles.title}>Page index 我是子应用 哈哈哈哈</h1>
</div>
);
}
网友评论