iframe 是在不同域名场景下通信的一种方式,
它的核心是 A 域名向 B 域名发送 postMessage 事件,然后 B 域名通过 document.addEventListener("message", handleMessage) 来监听传递过来的 postMessage 事件,得以实现跨域通信的诉求。
case:B 域名的点击事件,最终触发的是 A 域名的方法
B 域名(发送方)
1.全局封装 postMessage 方法
// 向父容器传递事件
export function _notifyParentWindow(message: any, targetOrigin: string = '*') {
if (window.parent !== window) {
window.parent.postMessage(message, targetOrigin)
}
}
2.发送 postMessage 方法给 A 域名
// 通知父容器:点击活动编辑按钮
export function notifyEditPage(pageInfo: any) {
_notifyParentWindow({
type: NOTIFY_TYPE.EDIT_PAGE,
pageInfo,
})
}
至此,当用户点击 B 域名里的编辑按钮时,B 域名就会向 A 域名发送 postMessage 事件进行通信,剩下的就是 A 域名接收这个 postMessage 事件的问题了
A 域名(接收方)
useEffect(() => {
const handlePostMessage = (event: MessageEvent) => {
if (event.data.type === NOTIFY_TYPE.EDIT_PAGE) {
openEditWindow() // 实现在 A 域名下的方法
}
// ...进一步判断 type,进行处理
}
window.addEventListener('message', handlePostMessage)
return () => {
window.removeEventListener('message', handlePostMessage) // 组件销毁时要连带销毁监听器
}
}, [])
当 A 域名接收到指定 type 类型的 postMessage 事件后,就会对应处理,完成跨域通信🎉