微前端必须动态创建iframe并由js管控生命周期,硬编码src会导致状态错乱;需设置唯一name、显式宽高样式、用postmessage通信并校验origin,url同步须手动桥接history。

直接用 <iframe src="xxx"></iframe> 标签硬加载子应用,不是微前端,只是静态嵌入;真要跑微应用,必须由 JS 主动管控生命周期、URL 同步、通信和错误恢复。
动态创建 iframe 是唯一可行的生产方式
硬编码 <iframe src="/cart.html"></iframe> 看似简单,但会导致切换子应用时残留 DOM、内存泄漏、无法响应路由变化。主应用必须用 JS 动态创建、销毁、复用 iframe 实例。
- 每次路由跳转前,先调用
iframe.remove()或清空容器节点,避免多个 iframe 堆积 - 给 iframe 设置唯一
name属性(如name="cart-app"),后续可通过window.frames['cart-app']定向访问 - 不要复用旧 iframe 并只改
src——这会触发页面重载但不重置 JS 执行环境,容易状态错乱 - 推荐封装一个
loadMicroApp(url, name)函数,统一处理创建、sandbox 设置、onload 监听和 postMessage 初始化
src 必须是合法可加载地址,否则静默失败
浏览器对 src 的校验极严:空字符串、javascript:void(0)、file:// 路径一律拦截,控制台常只报 net::ERR_FAILED,无明确提示。
- 本地开发必须起 HTTP 服务,例如
python3 -m http.server 8000,然后用http://localhost:8000/subapp/index.html - 生产环境强制用绝对路径,如
/micro/order.html,避免父页面在/admin/user/123下导致相对路径解析成/admin/user/micro/order.html - 动态赋值前加协议检查:
if (url && (url.startsWith('http') || url.startsWith('/'))) iframe.src = url - 禁止使用
about:blank占位再 later 赋值——部分浏览器会拒绝后续跨域src加载
宽高塌陷和跨域通信是两个高频“看不见”的坑
iframe 默认尺寸是 300×150px,在 Flex/Grid 容器中极易被压缩为 0×0,表现为“白屏”或“消失”,但实际已加载;跨域时 contentDocument 直接抛 DOMException: Blocked a frame from accessing a cross-origin frame,无降级路径。
- 必须显式设置样式:
style="width: 100%; height: 400px; border: none;";响应式用aspect-ratio: 16 / 9防拉伸 - 移动端需加
touch-action: auto和height: 100vh,否则滚动穿透失效 - 跨域通信只能靠
postMessage():发消息前确认iframe.contentWindow存在(等onload后);接收方必须校验event.origin,不能只看event.data.type - 子应用初始化完成后,应主动发
{ type: 'READY' },主应用据此才认为子应用真正就绪——onload只代表 HTML 加载完,JS 可能还没执行完
URL 同步和浏览器前进/后退必须手动桥接
iframe 不参与浏览器 history 栈,点后退按钮,主应用 URL 变了,iframe 还卡在旧页面;刷新页面后,iframe src 不会自动同步当前路由。
- 主应用调用
history.pushState()改变 URL 时,必须同步更新iframe.src并触发重载 - 监听
window.onpopstate,根据event.state中携带的子应用标识,重新加载对应 iframe - 建议在路由 state 中存一份
{ microApp: 'payment', path: '/checkout' },避免从 URL 字符串里解析出错 - 不要依赖
iframe.contentWindow.location.href反查——跨域时该属性不可读
最易被忽略的是:子应用加载完成 ≠ 可交互。你得等它发 MOUNTED 消息,而不是只信 onload;还有,所有 postMessage 的 targetOrigin 参数都不能写 '*',否则在严格 CSP 策略下会被浏览器丢弃。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











