前端如何使得两个项目之间通信,window.open + postMessage
一、背景
由于公司内部需求不断加大,一个项目无法满足,多个项目直接需满足互相通信,则需要解决跨域传递消息的问题
二、两个项目之间如何通信,如何解决解决跨域传递消息
1. A.html ( https://www.a.com )
<div @click="goDetail('参数id')">传递信息</div>
<script>
getMessage()
let timeOfmsg = null
function getMessage() {
// 接收消息
window.addEventListener('message', (e) => {
console.log('no 接收到数据')
if (e.data === 'getMsg') {
// @ts-ignore
console.log('接收到数据')
clearInterval(timeOfmsg)
}
})
}
// 跳转到画板编辑页面
function goDetail(id) {
let url = 'https://www.b.com'
// 打开画布
const targetWindow = window.open(`${url}?id=${id}`, '_blank')
// 发送消息
timeOfmsg.value = setInterval(() => {
console.log('已发送消息')
targetWindow.postMessage(localStorage.getItem('TOKEN'), url)
}, 1000)
}
</script>
2. B.html ( https://www.b.com )
<script> window.addEventListener( 'message', (event) => {
// 判断接收信息的来源是否来自于 https://www.a.com if (event.origin != 'https://www.a.com') return; // 将接收到的数据存储到本地 localStorage.setItem('TOKEN', event.data); // 返回消息,告知已收到数据 event.source.postMessage('getMsg', event.origin); }, false ); </script>
三、坑点
1. onload (失败)
window.open('xxx').onload = () => { window.postMessage(message, targetOrigin, [transfer]); }
2. setTimeout (失败,由于B网站不一定什么时候加载完成)
setTimeout(() => window.postMessage(this.userSession, targetUrl), 3000);
3. setInterval(成功,A网站定时器不断发送消息,当B网站接收到信息后,向A网站回复消息为已收到,关闭A网站的定时器)
let timeOfmsg = setInterval(() => { winopen.postMessage(this.userSession, targetUrl); }, 3000);