fetch 是微前端拉取子应用 html 的起点,仅负责获取字符串,后续需经 domparser 解析、路径重写、资源注入及沙箱执行;其关键约束包括跨域响应头、绝对 url、防缓存参数,且不可直接 innerhtml 插入。

Fetch 是微前端中拉取子应用 HTML 入口的起点,但它本身不执行加载逻辑,而是作为“数据获取通道”配合 JS 控制流完成解析、路径重写、资源注入和沙箱执行。真正起作用的是后续的 DOMParser 解析、script 动态创建、样式隔离处理等步骤。
Fetch 拉取 HTML 的关键约束
主应用调用 fetch(subAppUrl) 获取子应用 index.html 时,必须满足:
- 子应用服务端响应头需包含
Access-Control-Allow-Origin,否则跨域失败 - URL 必须是完整绝对地址(如
https://sub.example.com/index.html),不能是相对路径 - 建议加时间戳或哈希参数(如
?v=1.2.3)避免浏览器缓存旧 HTML - fetch 返回的是字符串,不是可执行 DOM——直接
innerHTML = htmlStr会跳过 script 执行、逃逸样式、绕过沙箱
Fetch 后必须走标准解析链路
拿到 HTML 字符串后,不能简单插入页面。主流框架(如 qiankun)实际执行的是:
- 用
new DOMParser().parseFromString(html, 'text/html')得到干净的 Document 对象 - 从
doc.head提取所有<link rel="stylesheet">和<style></style>,重写其中url(./xxx)为绝对路径 - 从
doc.body提取innerHTML作为模板内容,挂载到指定容器节点 - 遍历
doc.head中的<script></script>:外链脚本用new URL(src, response.url)补全地址后动态创建并插入;内联脚本交由沙箱(如execScripts)在隔离作用域中执行
Fetch 无法解决但必须规避的问题
Fetch 只管“拿”,不管“怎么用”。以下问题若不手动处理,会导致加载失败或污染主应用:
- 子应用 HTML 中的
<script src="./main.js"></script>是相对路径 → 主应用需重写为绝对地址,或子应用构建时设publicPath: 'auto' - 子应用 HTML 含
<script>window.xxx = ...</script>→ 若未进沙箱执行,会直接污染全局 window - 子应用用了
defer或async→ 这些属性会让脚本脱离 mount 生命周期控制,必须移除 - 子应用声明了
<base href="/sub/">但主应用没同步处理 → 图片、字体等静态资源仍会从主域名下加载,404
Fetch + import() 的协同升级路径
纯 HTML Entry 模式依赖 fetch + DOMParser,而更现代的 ESM 入口则转向 import():
- 子应用提供标准 ESM 入口(如
https://cdn.example.com/app/entry.js),导出bootstrap/mount/unmount - 主应用用
const mod = await import(url + '?t=' + Date.now())加载,天然支持 HMR、live binding 和import.meta - 此时 fetch 退居为辅助角色(例如用于预检入口文件 hash 是否变化),核心加载由
import()完成
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











