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>

四、案例效果

相关推荐
markyankee1011 分钟前
Vue.js 入门指南:从零开始构建你的第一个应用
vue.js
MrSkye3 分钟前
🔥JavaScript 入门必知:代码如何运行、变量提升与 let/const🔥
前端·javascript·面试
白瓷梅子汤7 分钟前
跟着官方示例学习 @tanStack-form --- Linked Fields
前端·react.js
爱学习的茄子11 分钟前
深入理解JavaScript闭包:从入门到精通的实战指南
前端·javascript·面试
zhanshuo42 分钟前
不依赖框架,如何用 JS 实现一个完整的前端路由系统
前端·javascript·html
火柴盒zhang43 分钟前
websheet在线电子表格(spreadsheet)在集团型企业财务报表中的应用
前端·html·报表·合并·spreadsheet·websheet·集团财务
讨厌吃蛋黄酥43 分钟前
智能前端新纪元:语音交互技术与安全实践全解析
javascript
khalil1 小时前
基于 Vue3实现一款简历生成工具
前端·vue.js
拾光拾趣录1 小时前
浏览器对队头阻塞问题的深度优化策略
前端·浏览器
用户8122199367221 小时前
[已完结]后端开发必备高阶技能--自研企业级网关组件(Netty+Nacos+Disruptor)
前端