iframe 实现跨域,两页面之间的通信

一、 背景

一个项目为vue2,一个项目为vue3,两个不同的项目实现iframe嵌入,并实现通信

二、方案

iframe跨域时,iframe组件之间常用的通信,主要是H5的possmessage方法

三、案例代码

父页面-vue2(端口号为127.0.0.1:8080)

复制代码
<template>
  <div>
    <div class="container">
      <iframe
        ref="iframeId"
        id="iframeId"
        src="http://127.0.0.1:8081"
        frameborder="0"
        border="0"
        hspace="0"
        vspace="0"
        scrolling="yes"
        height="100%"
        width="100%"
      ></iframe>
    </div>
  </div>
</template>
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator';

@Component({
  components: {},
})
export default class FeatureService extends Vue {
  // 定义一个方法,用于发送消息到iframe
  private postMessageToIframe() {
    // 设置延时,确保iframe已经加载完成
    setTimeout(() => {
      // 定义要发送的数据
      const iframeInfo = { isIframeParent: true };
      // 定义目标源
      const targetOrigin = 'http://127.0.0.1:8081';
      // 获取iframe引用
      const iframe = this.$refs.iframeId;
      // 向iframe发送消息
      iframe.contentWindow.postMessage(
        JSON.stringify(iframeInfo),
        targetOrigin
      );
    }, 500);
  }

  private mounted() {
    // 在组件挂载后,发送消息到iframe
    this.postMessageToIframe();

    window.addEventListener('message', this.handleMessage, false);
  }

  private handleMessage(event: MessageEvent) {
    // 通过origin对消息进行过滤,避免遭到XSS攻击
    if (event.origin === 'http://127.0.0.1:8081') {
      console.log('子页面传输过来参数', event.data);
    }
  }
}
</script>
<style lang="less" scoped>
.container {
  width: 100%;
  margin-top: -40px;
  height: 100vh;
  overflow: hidden;
  #iframeId {
    width: 100%;
    display: block;
  }
}
</style>

子页面-vue3, (端口号为127.0.0.1:8081)

复制代码
<template>
  <div>
    <!-- 顶部导航 -->
    <TopMenu v-if="!iframeParentInfo.isIframeParent" />

    <div class="demo-sidebar-container demo-full-width">
      <!-- 侧边栏 -->
      <SiderBar v-if="!iframeParentInfo.isIframeParent" />
      <!-- 内容容器 -->
      <ContentBox />
    </div>
  </div>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue'

const iframeParentInfo = ref({})

const messageHandler = (e) => {
  // 通过origin对消息进行过滤,避免遭到XSS攻击
  if (e.origin !== 'http://127.0.0.1:8080') return
  if (typeof e.data === 'string') {
    parseData(e.data)
  }
}

const parseData = (data) => {
  try {
    iframeParentInfo.value = JSON.parse(data)
    console.log('父页面传输过来参数', data)
  } catch (error) {
    console.error('解析JSON出错', error)
    iframeParentInfo.value = {}
  }
}

onMounted(() => {
  // 获取 父向 子(iframe) 传递的信息
  window.addEventListener('message', messageHandler)

  // 子(iframe)向父传递信息
  window.parent.postMessage('Hello Parent!', '*')
})
</script>

四、案例效果

相关推荐
恋猫de小郭7 分钟前
Flutter 2026 Roadmap 发布,未来计划是什么?
android·前端·flutter
时清云16 分钟前
2025-年终总结
前端
Esaka_Forever20 分钟前
Promise resolve 的基础用法
前端·javascript
a11177624 分钟前
卡通风格 UI 组件库html (TRIZ UI Kit [特殊字符])
前端·ui·html
鳄鱼杆44 分钟前
虚拟机 | 如何通过域名访问虚拟机中的Web服务?
前端
赵_叶紫1 小时前
Vue 3 从基础到组合式 API 全解析
vue.js
We་ct1 小时前
LeetCode 236. 二叉树的最近公共祖先:两种解法详解(递归+迭代)
前端·数据结构·算法·leetcode·typescript
用泥种荷花2 小时前
【LangChain.js学习】 提示词模板
前端
认真的薛薛2 小时前
2-监控:elk采集各种日志并出图
前端·chrome·elk
hypnos_xy2 小时前
Vue3 工程构建
vue.js·前端框架