Skip to content

Iframe弹窗页面发送消息

理论知识

postMessage

otherWindow.postMessage(message, targetOrigin, [transfer]);
  • otherWindow:其他窗口的引用,如 iframe的contentWindow、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames。
  • message:将要发送到其他window的数据。
  • targetOrigin:指定那些窗口能接收到消息事件,其值可以是字符串 “*” 表示无限制,或者是一个URI。
  • transfer:是一串和message同时传递的Transferable对象,这些对象的所有权将被转移给消息的接收方,而发送方将不再保留所有权。

发送消息

父向子发送消息

IMPORTANT

注意: 一定是页面加载完成后在发送消息,否则会因为 iframe 未加载完成报错。

js
window.onload = function(){
    document.getElementById('child').contentWindow.postMessage("主页面消息", "http://b.com/iframepage.html")
}

子页面接收消息

js
window.addEventListener('message', function(event){
    console.log(event);
    console.log("收到" + event.origin + "消息:" + event.data); //收到http://a.com消息:主页面消息
}, false);

子向父发送消息

js
window.top.postMessage("子页面消息收到", 'http://a.com/main.html')
  • top 是window.top

父页面收到消息

js
window.addEventListener('message', function(event){
    document.getElementById('message').innerHTML = "收到" + event.origin + "消息:" + event.data;
}, false);

vue项目中对iframe发送数据

vue
<template>
  <iframe ref="aiIframe" :src="aiIframeUrl" frameborder="0" style="width: 100%; height: 75vh" />
</template>

<script>
export default {
  name: 'AiIframe',
  props: {
    doc: {
      type: Object,
      default: () => {
        return {}
      },
    },
  },
  data() {
    return {
      user: JSON.parse(localStorage.getItem('User')),
    }
  },
  computed: {
    aiIframeUrl() {
      return `https://www.istr.cn/ai?name=${encodeURIComponent(this.user.name)}`
    },
  },
  mounted() {
    this.$refs.primeaiIframe.addEventListener('load', this.handleLoadEvent)
    window.addEventListener('message', this.handleMessage)
  },
  beforeDestroy() {
    this.$refs.primeaiIframe?.removeEventListener('load', this.handleLoadEvent)
    window.removeEventListener('message', this.handleMessage)
  },
  methods: {
    sendData() {
      const data = {
        id: this.doc.id,
        title: this.doc.title,
      }
      console.log('将要发送的数据:', data)

      try {
        this.$refs.aiIframe.contentWindow.postMessage(data, '*')
        console.log('数据发送成功!')
      } catch (error) {
        console.error('发送数据时出错:', error)
      }
    },
    handleLoadEvent() {
      console.log('AI iframe loaded')
      this.sendData()
    },
    handleMessage(evt) {
      console.log('Received message from iframe:', evt.data)
      if (evt.data === 'aiClose') {
        this.$emit('close')
      }
    },
  },
}
</script>

iframe组件