vue iframe结合postMessage实现跨域通信

373 阅读2分钟

vue iframe结合postMessage实现跨域通信

一、前言

什么是iframe

iframe也称作嵌入式框架,嵌入式框架和框架网页类似,它可以把一个网页的框架和内容 嵌入在现有的网页中

什么是postMessage

PostMessage是Windows API(应用程序接口) 中的一个常用函数,用于将一条消息放入到消息队列中。消息队列里的消息通过调用GetMessagePeekMessage取得。

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

其他窗口的一个引用,比如 iframecontentWindow 属性、执行 window.open 返回的窗口对象、或者是命名过或数值索引的 window.frames

message

要发送的数据。它将会被结构化克隆算法序列化,所以无需自己序列化(部分低版本浏览器只支持字符串,所以发送的数据最好用JSON.stringify() 序列化)。

targetOrigin

通过 targetOrigin 属性来指定哪些窗口能接收到消息事件,其值可以是字符串 '*'(表示无限制)或者一个 URI(如果要指定和当前窗口同源的话可设置为"/")。在发送消息的时候,如果目标窗口的协议、主机地址或端口号这三者的任意一项不匹配 targetOrigin 提供的值,那么消息就不会发送。

vue组件中实现

首先在mounted生命周期获取iframecontentWindow属性

mounted() {
  this.iframeWin = this.$refs.iframe.contentWindow;
},

父页面向子页面传值

this.iframeWin.postMessage({
    msg: 'success',
    data: "我是父页面的"
}, '*')

子页面传值

window.parent.postMessage({
     data: {
       code:"success",
       test:"我是子页面"
     }
   }, '*');