用iframe实现单个系统页面在多个系统中复用

背景:

因为领导决策,将 A 系统复制出一份代码改头换面变成 B 系统,并要求在 B 系统开发一个模块给供应商使用,开发完了,好的,现在领导又想要把这个页面搬到 A 系统给公司内部工程师使用了。。。。。。

矛盾点:

  1. 如果直接将文件复制过来用,以后每次更新都要两边改,维护特别困难;

  2. 如果把这个页面单独封装成一个大的组件去复用,工作量更加是无敌庞大。

遂:直接 iframe 嵌入

这样做可以实现只在一个地方维护该模块,大大减少工作量。

前提是:

  1. 已经再三确认,以后 A、B 系统中的这个页面是一致的,不会进行差异化定制;

  2. 各项细小的操作权限和 B 系统中的保持一致,直接在后台中对B系统的权限规则进行勾选

问题:

  1. 测试服和正式服的页面地址不同;

  2. 页面存在顶部和侧面菜单栏

解决:

  1. 在 A 系统中新增一个路由,指向一个放着 iframe 的Vue文件;
html 复制代码
<template>
  <div class="chat-container">
    <iframe
      :src="src"
      frameborder="0"
      width="100%"
      height="100%"
      id="myiframe"
      sandbox="allow-scripts allow-same-origin allow-forms"
      @load="handleIframeLoad"
    />
  </div>
</template>

<script>
export default {
  name: 'FQATest',
  components: {},
  props: {},
  data() {
    return {}
  },
  computed: {
    src() {
      // 尝试添加参数来跳过有问题的认证流程
      const baseUrl = process.env.NODE_ENV === 'production'
        ? '正式服页面地址'
        : '测试服页面地址'

      return `${baseUrl}?skipAuth=true&bypassTokenCheck=true`
    }
  },
  created() {},
  mounted() {
  },
  methods: {
    handleIframeLoad() {
      // 添加错误捕获
      const iframe = document.getElementById('myiframe')
      iframe.contentWindow.onerror = function(msg, url, line) {
        console.log('iframe错误:', msg, url, line)
        return true // 阻止错误冒泡
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.chat-container {
  height: calc(100vh - 85px);
}
</style>
  1. 在 B 系统中的 Layout 布局组件中进行环境判断,如果是在 iframe 嵌套环境下,那么只显示主内容,否则正常显示(有顶部和侧边菜单栏)。

核心代码:

html 复制代码
<template>
<div>

  <!-- 系统内部 -->
  <div :class="classObj" class="app-wrapper" v-if="!iframeEmbedded">
    <div
      v-if="device === 'mobile' && sidebar.opened"
      class="drawer-bg"
      @click="handleClickOutside"
    />
    <sidebar class="sidebar-container" />
    <div class="main-container">
      <div v-if="showHeader" :class="{ 'fixed-header': fixedHeader }">
        <navbar />
        <tags-view v-if="needTagsView" />
      </div>
      <app-main />
    </div>
  </div>

  <!-- 被嵌入iframe -->
  <div v-else>
    <app-main />
  </div>
</div>
</template>

逻辑判断:

javascript 复制代码
  data() {
    return {
      iframeEmbedded: false // 是否被iframe嵌入
    }
  },
  mounted() {
    this.checkIframeEmbedded()
  },
  methods: {
    // 检测是否被iframe嵌入
    checkIframeEmbedded() {
      try {
        // 方法1: 检查window.self和window.top是否相同
        if (window.self !== window.top) {
          this.iframeEmbedded = true
          console.log('✅ 检测到iframe嵌入: window.self !== window.top',this.iframeEmbedded)
          return true
        }

        // 方法2: 检查window.frameElement是否存在
        if (window.frameElement) {
          this.iframeEmbedded = true
          console.log('✅ 检测到iframe嵌入: window.frameElement存在',this.iframeEmbedded)
          return true
        }

        // 方法3: 检查URL参数中是否包含iframe标识
        const urlParams = new URLSearchParams(window.location.search)
        if (urlParams.has('iframe') || urlParams.has('embedded')) {
          this.iframeEmbedded = true
          console.log('✅ 检测到iframe嵌入: URL参数包含iframe标识',this.iframeEmbedded)
          return true
        }

        // 方法4: 检查referrer是否来自同一域名(可选)
        if (document.referrer && document.referrer !== '' &&
            document.referrer !== window.location.href) {
          // 如果referrer存在且不是当前页面,可能是被嵌入
          const currentDomain = window.location.hostname
          const referrerDomain = new URL(document.referrer).hostname
          if (referrerDomain !== currentDomain) {
            this.iframeEmbedded = true
            console.log('✅ 检测到iframe嵌入: referrer来自不同域名',this.iframeEmbedded)
            return true
          }
        }
        this.iframeEmbedded = false
        console.log('❌ 未检测到iframe嵌入',this.iframeEmbedded)
        return false
      } catch (error) {
        // 如果出现跨域错误,说明被iframe嵌入
        console.log('iframe检测出现错误,可能被嵌入:', error)
        this.iframeEmbedded = true
        return true
      }
    },
  }

这样就大功告成啦!以后只需要在 B 系统中维护该模块即可,A 系统这边也会同步更新。

相关推荐
m0_736034853 小时前
1.28笔记
前端·chrome·笔记
IT陈图图3 小时前
构建 Flutter × OpenHarmony 跨端带文本输入对话框示例
开发语言·javascript·flutter
丝斯20113 小时前
AI学习笔记整理(63)——大模型对齐与强化学习
人工智能·笔记·学习
叫我辉哥e18 小时前
### 技术文章大纲:C语言造轮子大赛
c语言·开发语言
奔跑的web.8 小时前
TypeScript 装饰器入门核心用法
前端·javascript·vue.js·typescript
阿蒙Amon8 小时前
TypeScript学习-第1章:入门
javascript·学习·typescript
winfredzhang8 小时前
实战复盘:如何用 HTML+JS+AI 打造一款“影迹”智能影视管理系统
javascript·html·json·加载·搜索·保存·电影接口
集成显卡8 小时前
Lucide Icons:一套现代、轻量且可定制的 SVG 图标库
前端·ui·图标库·lucide
guygg889 小时前
NOMA功率分配与64 QAM调制中的SIC的MATLAB仿真
开发语言·matlab
pas1369 小时前
37-mini-vue 解析插值
前端·javascript·vue.js