vue iframe结合postMessage实现跨域通信
一、前言
什么是iframe
iframe也称作嵌入式框架,嵌入式框架和框架网页类似,它可以把一个网页的框架和内容 嵌入在现有的网页中
什么是postMessage
PostMessage是Windows API(应用程序接口) 中的一个常用函数,用于将一条消息放入到消息队列中。消息队列里的消息通过调用GetMessage和PeekMessage取得。
window.postMessage() 方法可以安全地实现跨源通信。通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同协议(通常为https
),端口号(443为https的默认值
),以及主机 (两个页面的模数 Document.domain
设置为相同值) 时,这两个脚本才能相互通信。window.postMessage()
方法提供了一种受控机制来规避此限制,只要正确的使用,这种方法就很安全。
二、应用场景
在一个项目中通过iframe嵌入另一个项目的页面,需要实现页面之间的父子通信
iframe引入页面
<iframe id="myIframe" name="myIframe" :src="src" ref="iframe" width="500px" height="500px"></iframe>
data(){
return {
src:"iframe链接"
}
}
问题:iframe内嵌的是另一个项目页面,假设子页面有一个按钮事件,如何在父页面知道触发了这个事件,这个时候POSTMessage就派上了用场
postMessage 实现父子页面通信
语法
otherWindow.postMessage(message, targetOrigin, [transfer]);
otherWindow
其他窗口的一个引用,比如 iframe
的 contentWindow
属性、执行 window.open
返回的窗口对象、或者是命名过或数值索引的 window.frames
。
message
要发送的数据。它将会被结构化克隆算法序列化,所以无需自己序列化(部分低版本浏览器只支持字符串,所以发送的数据最好用JSON.stringify()
序列化)。
targetOrigin
通过 targetOrigin
属性来指定哪些窗口能接收到消息事件,其值可以是字符串 '*'(表示无限制)或者一个 URI(如果要指定和当前窗口同源的话可设置为"/")。在发送消息的时候,如果目标窗口的协议、主机地址或端口号这三者的任意一项不匹配 targetOrigin
提供的值,那么消息就不会发送。
vue组件中实现
首先在mounted生命周期获取iframe
的contentWindow
属性
mounted() {
this.iframeWin = this.$refs.iframe.contentWindow;
},
父页面向子页面传值
this.iframeWin.postMessage({
msg: 'success',
data: "我是父页面的"
}, '*')
子页面传值
window.parent.postMessage({
data: {
code:"success",
test:"我是子页面"
}
}, '*');