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>

四、案例效果

相关推荐
萧行之1 小时前
可视化技术复盘:从图形语法看 D3、Vega-Lite、ECharts、Observable Plot
前端·学习·数据可视化
尾善爱看海9 小时前
Vue 面试收官篇:SSR、性能优化落地、30 道高频面试题精讲(附标准答案)
前端·javascript·vue.js·面试·vue
weixin_BYSJ19879 小时前
【计算机毕设】基于SpringBoot与Vue的文物保护档案管理系统08621
vue.js·spring boot·spring cloud·微服务·架构·django·课程设计
Bs_MoneyMagnet10 小时前
基于springboot+vue的个人健康管理系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·vue3·springboot3·计算机毕业设计
驳是10 小时前
一个组件,提升 react-router 开发的幸福感
前端·preact
GreenTea10 小时前
OpenAI Agents API 上手实测:一次调用把整个 agent loop 甩给 OpenAI
前端·后端·算法
星云API技术支持10 小时前
企业微信二次开发:群权限设置、成员管理与群资料维护的接口组合实践
java·前端·企业微信
京东云开发者10 小时前
81.8 秒的视频,我们改了 15 个版本:一次纯 Codex 驱动的 AI-native 视频实践
前端·aigc
Csvn11 小时前
TypeScript 大型项目架构:从单体 tsconfig 到分层可扩展的工程
前端
Bs_MoneyMagnet12 小时前
基于springboot+vue的心理咨询预约与随访平台的设计与实现 源码+文档
vue.js·spring boot·后端·spring·毕业设计·旅游·计算机毕业设计