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>

四、案例效果

相关推荐
深蓝AI2 小时前
Meta 开源用了八年的设计系统 astryx:连坐两天 GitHub 总榜第一,组件库开始写给 agent 的说明书
前端·人工智能
ruanno_top3 小时前
轮播每 3 秒自己翻页:键盘停不下来,读屏也不知道换了页
vue.js
IT_陈寒3 小时前
Vue的watch把我坑惨了,原来要这样用才靠谱
前端·人工智能·后端
1-1=03 小时前
Vue 3 模板语
前端·javascript·vue.js
用户7610304473713 小时前
【转战智能眼镜开发】ROKID AIUI 小游戏 亚马逊标枪项目实战讲解
前端
风卿3 小时前
看着AI写代码太孤独了,来欣赏星云吧:一个DSH 装饰插件
前端·javascript
牧艺3 小时前
弹层不用再手算坐标了:CSS Anchor Positioning 从原理到可上线
前端·javascript·css
用户老李4 小时前
YOLO 目标检测自学教程 07:YOLOv3——多尺度预测
前端
moshuying4 小时前
ESP32 墨水屏金价牌(上):从点亮到把图片推过去
前端
李剑一4 小时前
别再抬杠,前端岗已经没了!无论前后端,我们最终都要成“全干”工程师
前端·面试