domparser 解析是 html entry 加载不可跳过的一步,直接使用 container.innerhtml = htmlstring 会导致子应用内联 script/style 逃逸至主应用全局作用域,引发脚本污染、样式泄漏和白屏;必须用 new domparser().parsefromstring(html, 'text/html') 获取标准 document 对象,再提取 body 内容与 head 中资源节点并逐项处理,确保路径绝对化、脚本沙箱执行、样式注入容器或 shadowroot;子应用资源路径须为绝对 url,构建时 publicpath 设为完整域名,运行时通过 new url(attrvalue, response.url) 重写;动态 fetch 需沙箱重绑定 window.fetch;iframe 是唯一真正 html 层级 js 沙箱,同域下应设 src="about:blank" 后 write 注入 html 并显式设置 base;样式卸载依赖容器移除触发 cssom 重建,但子应用越界操作 document.head/body(如动态 appendstyle、组件库挂载到 body、全局 style)将导致隔离失效——此问题比 js 沙箱更隐蔽且高频。

DOMParser 解析是 HTML Entry 加载不可跳过的一步
直接 container.innerHTML = htmlString 会导致子应用内联 <script></script> 和 <style></style> 逃逸到主应用全局作用域,脚本污染、样式泄漏、白屏问题几乎必然发生。浏览器对 innerHTML 的解析不经过沙箱控制逻辑,也不触发任何隔离机制。
必须用 new DOMParser().parseFromString(html, 'text/html') 得到标准 Document 对象,再从中提取内容:
-
doc.body.innerHTML作为挂载模板(不含原始) -
doc.head.querySelectorAll('script, link[rel="stylesheet"], style')提取所有资源节点 - 逐个处理:外链
src/href补全为绝对 URL;内联<script></script>交由沙箱执行;<style></style>内容提取后注入容器或shadowRoot.adoptedStyleSheets
资源路径必须是绝对 URL,否则 fetch 必 404
子应用独立运行时 src="./main.js" 没问题,但被主应用 fetch 后执行时,当前 base 是主应用域名,相对路径会拼成 https://main.com/./main.js,直接失败。
构建和运行时需双保险:
- 子应用 Webpack 配置
publicPath必须设为完整协议域名,如'https://sub.example.com/',禁用'auto'或'./' - 主应用解析 HTML 前,对每个
script[src]、link[href]、style中的url(...)调用new URL(attrValue, response.url)重写路径 - 若子应用含动态
fetch('/api'),还需在沙箱中重绑定window.fetch,补全 base URL
iframe 是唯一真正 HTML 层级的 JS 沙箱
Proxy 沙箱、快照沙箱都是 JS 运行时模拟,子应用仍能通过 eval、Function 构造器、with、Symbol.unscopables 等方式逃逸。只有 iframe 拥有独立的 window、document、事件循环和 JS 执行上下文,是浏览器引擎级隔离。
同域下安全使用方式:
- 创建
iframe.src = 'about:blank',不发网络请求 - 通过
iframe.contentWindow获取干净上下文 - 用
doc.write()注入子应用 HTML,并显式设置<base href="https://sub.example.com/"> - 严禁调用
win.eval()或win.execScript(),那等于把代码拉回主上下文
样式卸载靠 DOM 移除,但动态插入的 style 必须禁用
HTML Entry 模式下,卸载子应用时移除整个容器节点,浏览器自动重建 CSSOM,初始加载的 <style></style> 和 <link> 会立即失效——这是它“天然支持样式隔离”的原因。
但以下行为会让这个机制完全失效:
- 子应用调用
document.head.appendChild(<style>)</style>,该标签不在容器内,卸载不清理 - Ant Design、Element Plus 等组件库的弹窗默认挂载到
document.body,其内联样式脱离容器边界 - 子应用 HTML 中含全局
<style>body { margin: 0 }</style>,DOMParser 解析后挂载进容器,但未启用样式快照机制时无法回收
真实项目里,90% 的样式残留问题都出在子应用越界操作 document.head 或 document.body,而不是框架没配好。这点比 JS 沙箱更难监控,也更容易被忽略。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











