跨域跨窗口通信有很多方案都可以解决,今天我们来说说如何使用 Post Messge
基本使用
发送消息
otherWindow.postMessage(message, targetOrigin, [transfer]);
otherWindow 是指其他窗口的一个引用 比如:
iframe的contentWindow属性- 执行
window.open返回的窗口对象 - 是命名过或数值索引的
window.frames等
关键其实在于 otherWindow 或者叫做 targetWindow 更加准确,是指你要发送信息的目标页面的 window 对象,直接 window.postMessage() 调用的当前窗口的 window 对象,相当于自己给自己发,目标页当然接收不到了。
关于 targetWindow 的获取根据弹出方式不同分为两种
- 弹出
iframe使用window.top或者window.parent来获取,二者的区别在于 window.parent 返回当前窗口的直接父对象,而 window.top 返回最顶层的窗口对象 window.open()打开新窗口 使用window.opener获取
接收消息
window.addEventListener('message', function (e) {
console.log(e.data);
}, false)
应用场景
假设我们有这样一个需求:
A页面有一个登录按钮,点击后打开一个新窗口B(A,B页面不同源),新窗口B页面内输入账号秘密验证后,通知A窗口已经登录成功。
// A页面
// 1. 监听 message 事件,监听事件会掉
// 2. 点击按钮,打开窗口
<body>
<button id='login'>去登录</button>
<script>
let newWindow
login.onclick=function(){
newWindow = window.open('./b.html','Login Page','height=400,width=400,top=20,left=20')
}
window.addEventListener('message', function (e) {
if(e.data==='login success'){
console.log('登录成功')
newWindow?.close() // 关闭新窗口
}
}, false)
</script>
</body>
// B页面
<body>
<button id="loginSuccess">点击登录</button>
<script>
let targetWindow = window.opener; // 获取打开此页面的window对象
loginSuccess.onclick=function(){
targetWindow.postMessage('login success', '*') // 第二个参数可指定发送的目标URL,*代表所有
}
</script>
</body>
如果B窗口打开方式是在A页面内打开Iframe,那么 targetWindow 是 window.parent 而不是 window.opener