利用iframe联合跨仓库路由模块

需求背景

两个有路由转跳关系的模块(模块A和B,AB可以通过路由互相转跳)分散在两个不同的项目中(比如迁移仓库没全迁移完,只迁移了A模块),此时后端需要联调AB模块整体功能。

此时可以借助一个父项目,把A模块和B模块通过iframe嵌入,从而实现功能的组合。

实现思路

把A模块与B模块中路由转跳相关的代码修改为与父应用的通信(window.parent.postMessage),目的是借助父应用与另一个模块通信,父应用中就可以通过接收到的路由参数拼接出目标的路由地址,然后操作另一个模块的iframe的src属性,从而完成正常的路由转跳。

demo模拟

结构说明

index.html相当于嵌入了很多子项目的主应用,里面通过iframe嵌入了child.html以及一个哔哩哔哩主页的iframe。

child.html相当于一个子应用,它可以读取一个id,从而向主应用发送消息,主应用监听消息事件,操作b站iframe的src,从而做到子应用之间的通信。

运行方式

通过live-server启动index.html与child.html

在index.html应用中:操作上方child.html里的input,输入用户id,点击按钮。观察下方iframe的变化

代码分析

child.html

html 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>另一个iframe页面</title>
  </head>
  <body>
    <div>
      请输入用户主页id:<input type="text" />
      <button onclick="onBtnClick()">转跳至b站指定用户主页</button>
    </div>
    <script>
      function onBtnClick() {
        const input = document.querySelector("input");
        const userId = input.value;
        const params = {
          targetUrl: "https://space.bilibili.com",
          userId,
        };
        // 当本身作为一个iframe被嵌入时,通过window.parent访问自己所在的父应用
        // window.parent.postMessage中的xxxWindow.postMessage方法即触发xxxWindow的message事件,第一个参数params即为传递的参数,第二个参数可以为具体的URI,只有URI与xxxWindow同源时xxxWindow才能接受到message,或者"*",表示不限制
        // 第二个参数为具体URI时意义需确定,总之就是同源限制
        window.parent.postMessage(params, "*");
      }
    </script>
  </body>
</html>

index.html

html 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <style>
    .app {
      display: flex;
      flex-direction: column;
      height: 100vh;
    }
    .page2 {
      flex: 1;
    }
  </style>
  <body>
    <div class="app">
      <iframe
        src="http://127.0.0.1:5500/child.html"
        width="100%"
        height="40px"
        class="page1"
      ></iframe>
      <div class="page2">
        <iframe
          width="100%"
          frameborder="no"
          height="100%"
          src="https://www.bilibili.com/"
        ></iframe>
      </div>
    </div>
    <script>
      const page1 = document.querySelector(".page1");
      const page2 = document.querySelector(".page2");
      // 父应用监听child.html应用的message事件,并且操作b站iframe(视为另一个子应用)的src
      window.addEventListener("message", (e) => {
        const { targetUrl, userId } = e.data || {};
        if (targetUrl && userId) {
          page2.children[0].src = `${targetUrl}/${userId}`;
        }
      });
    </script>
  </body>
</html>

关于子应用样式

我们可以在父应用中在子应用的iframe的外层套一个div,这个盒子flex布局,并给iframe设置flex: 1;样式,可以封装成一个组件,伪代码:

html 复制代码
<div flex width=props.width height=props.height>
  <iframe flex:1>
  </iframe>
</div>

子应用的展示大小(空间)此时就由父应用中组件的props进行控制,我们的子应用最好设计成响应式的,以满足父应用中分配各种空间大小时,子应用的正常展示!

源码

gitee仓库地址

相关推荐
水银嘻嘻4 小时前
12 web 自动化之基于关键字+数据驱动-反射自动化框架搭建
运维·前端·自动化
小嘟嚷ovo5 小时前
h5,原生html,echarts关系网实现
前端·html·echarts
十一吖i5 小时前
Vue3项目使用ElDrawer后select方法不生效
前端
只可远观5 小时前
Flutter目录结构介绍、入口、Widget、Center组件、Text组件、MaterialApp组件、Scaffold组件
前端·flutter
周胡杰5 小时前
组件导航 (HMRouter)+flutter项目搭建-混合开发+分栏效果
前端·flutter·华为·harmonyos·鸿蒙·鸿蒙系统
敲代码的小吉米6 小时前
前端上传el-upload、原生input本地文件pdf格式(纯前端预览本地文件不走后端接口)
前端·javascript·pdf·状态模式
是千千千熠啊6 小时前
vue使用Fabric和pdfjs完成合同签章及批注
前端·vue.js
九月TTS6 小时前
TTS-Web-Vue系列:组件逻辑分离与模块化重构
前端·vue.js·重构
我是大头鸟7 小时前
SpringMVC 内容协商处理
前端
Humbunklung7 小时前
Visual Studio 2022 中添加“高级保存选项”及解决编码问题
前端·c++·webview·visual studio