利用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仓库地址

相关推荐
zach7 分钟前
前端落地实战:Next.js 项目 Nginx + PM2 生产部署全流程(附踩坑总结)
前端·pm2·next.js
overmind16 分钟前
oeasy教h5前端001 修改的乐趣_直接修改在线网页
前端
只睡四小时20 分钟前
JS 手写 D-pad 空间导航:电视端焦点引擎实战
android·开发语言·前端·javascript·ecmascript·hls·空间导航
恋猫de小郭23 分钟前
Android 原生的 Compose A2UI 也来了,你还抱着 XML 养老吗?
android·前端·flutter
庄园特聘拆椅狂魔24 分钟前
从连连看到粒子消散——前端小游戏与视觉特效的技术选型
前端
JudithHuang40 分钟前
React 常用 Hooks
前端·react.js·前端框架
sycmancia2 小时前
Qml——Window元素使用
前端
每天都好困2 小时前
03 AR 投影与误差修正:把地图上的点贴到视频画面上
前端
每天都好困2 小时前
04 地图图层封装:像管理 Photoshop 图层一样管理地图元素
前端
去伪存真2 小时前
构建你的第一个 DevOps AI Agent:自动化捕获、分析并修复 CI 故障
前端·agent