用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 系统这边也会同步更新。

相关推荐
亓才孓1 天前
多态:编译时看左边,运行时看右边
java·开发语言
bl4ckpe4ch1 天前
用可复现实验直观理解 CORS 与 CSRF 的区别与联系
前端·web安全·网络安全·csrf·cors
2501_941878741 天前
在奥克兰云原生实践中构建动态配置中心以支撑系统稳定演进的工程经验总结
开发语言·python
weixin_443297881 天前
Python打卡训练营第31天
开发语言·python
围炉聊科技1 天前
Vibe Kanban:Rust构建的AI编程代理编排平台
开发语言·rust·ai编程
阿珊和她的猫1 天前
Webpack中import的原理剖析
前端·webpack·node.js
测绘小沫-北京云升智维1 天前
大疆无人机常见故障提示及应对指南
经验分享·无人机
hqwest1 天前
码上通QT实战04--主窗体布局
开发语言·css·qt·布局·widget·layout·label
leiming61 天前
c++ qt开发第一天 hello world
开发语言·c++·qt