<link rel="import"> 已被标准删除,Chrome 73 起彻底废弃,Firefox 和 Safari 从未支持;应改用 fetch() + DOMParser 手动加载解析 HTML 片段,并注意 MIME 类型、跨域、节点导入及脚本执行等细节。

HTML <link rel="import"> 已被移除,别再用了
Chrome 73 起彻底废弃 <link rel="import">,Firefox 和 Safari 从未支持。现在用它只会加载失败、控制台报 DOMException: Failed to execute 'import' on 'Document': HTML Imports is not supported。这不是兼容性问题,是标准已删除——想靠它做模块化导入或解析 HTML 片段,路径从一开始就是错的。
替代方案:用 fetch() + DOMParser 手动解析 HTML 文件
要动态加载并解析外部 HTML(比如组件模板、片段),得自己拉取、解析、注入。核心链路是:fetch(url) → response.text() → new DOMParser().parseFromString(html, 'text/html') → 提取节点(如 doc.querySelector('#template'))→ 插入目标容器。
- 必须指定 MIME 类型为
'text/html',否则DOMParser可能按 XML 解析,导致自闭合标签(如<img>)解析失败 - 跨域时需服务端配
Access-Control-Allow-Origin,否则fetch直接拒绝 - 解析后得到的是独立文档对象(
Document),不能直接appendChild,得用importNode()或提取子节点(如doc.body.children)
常见错误:把 HTML 字符串当 DOM 节点直接操作
拿到 fetch 返回的 HTML 字符串后,有人会写 el.innerHTML = htmlString 就完事。这看似简单,但会跳过资源加载(<script> 不执行、<link> 不生效)、丢失事件绑定上下文、且无法精细控制解析逻辑(比如只取某个 <template> 内容)。
- 若需执行脚本,得手动创建
<script>标签并append到 document,且注意同源限制 - 若原 HTML 含相对路径(如
src="img/logo.png"),解析后这些路径仍以当前页面为基准,不会自动重写 - 用
innerHTML会触发多次重排,大量片段建议先用DocumentFragment中转
轻量封装建议:写个 importHTML() 工具函数
没必要每次都重复写 fetch + DOMParser,封装成函数更可控:
立即学习“前端免费学习笔记(深入)”;
async function importHTML(url, selector = 'body > *') {
const res = await fetch(url);
if (!res.ok) throw new Error(`HTTP ${res.status}: ${url}`);
const html = await res.text();
const doc = new DOMParser().parseFromString(html, 'text/html');
return [...doc.querySelectorAll(selector)];
}
调用时可精准提取目标内容:const nodes = await importHTML('./header.html', '#header');。注意:这个函数不处理样式隔离、脚本执行或 Shadow DOM,复杂场景得配合 <iframe> 或构建时预处理。
真正麻烦的不是怎么加载,而是加载后如何管理作用域、生命周期和资源清理——这些没法靠一次 fetch 解决,得结合具体框架或应用架构来设计。



















