原生HTML无法直接include页眉页脚,因其标准不支持类似PHP的include或JS的import语法;浏览器加载单个HTML文件时不会主动解析插入其他片段,所有复用需借助构建工具(如Eleventy、Hugo)预编译拼接,或谨慎使用底部注入的JS字符串方案。

纯静态 HTML 网站里反复粘贴同一段 <header> 或 <footer>,不是“写得快”,是埋雷——下次改导航,你得手动开 37 个文件挨个找、挨个替。
为什么原生 HTML 无法直接 include 页眉页脚
HTML 标准本身不支持类似 PHP 的 include 或 JS 的 import 语法。浏览器加载单个 HTML 文件时,不会主动解析并插入其他 HTML 片段。所有“复用”都是开发者自己想办法绕过去的结果,不是语言原生能力。
常见错误现象:
– 直接复制粘贴 <nav>…</nav> 到每个页面
– 用 JS 动态 fetch 后 innerHTML 插入,但 SEO 友好性差、首屏白屏明显
– 误以为 <iframe> 是解法,结果导致样式隔离、跳转异常、无障碍支持断裂
- 原生 HTML5 没有
<include>标签(别信某些过时教程) -
<object>和<embed>在现代语义化和可访问性要求下基本弃用 - 服务端 SSI(Server-Side Includes)虽可用,但依赖 Apache/Nginx 配置,静态托管平台(如 GitHub Pages、Vercel static)默认不启用
用 build 工具做预编译拼接(最稳妥的落地方式)
核心思路:开发时写碎片(header.html、footer.html),构建时自动合并成完整 HTML。不依赖运行时 JS,不影响 SEO,也不增加 HTTP 请求。
立即学习“前端免费学习笔记(深入)”;
典型工具链选择:
-
eleventy(推荐):零配置即可识别_includes/目录,用{% include "header.njk" %}写模板,输出纯静态 HTML -
Hugo:用{{ partial "header.html" . }},适合已有 Markdown 内容迁移 -
webpack + html-webpack-plugin:需配html-loader和raw-loader,适合已用 webpack 的前端项目
关键注意点:
– 所有 include 路径必须是构建时可解析的相对路径,不能是运行时 fetch('/header.html')
– 不要试图在 .html 文件里直接写模板语法(如 {% include %}),它不会被浏览器执行,只对构建工具生效
– 构建后检查生成的 HTML 源码,确认片段确实已内联,而非留下未处理的模板标记
轻量级方案:用 JS 加载但规避首屏问题
如果项目实在无法引入构建流程(比如临时维护一个老站点),JS 方案不是不能用,但必须解决两个硬伤:白屏、SEO。
- 把
<header>写在 HTML 底部(</body>前),用document.write()或insertAdjacentHTML()注入——避免阻塞主内容渲染 - 服务端已有的
<!--#include file="header.html"-->若可用,优先用它(SSI),比客户端 JS 更可靠 - 绝对不用
fetch().then(() => { document.getElementById('header').innerHTML = ... })这类异步注入,会导致 LCP(最大内容绘制)延迟、搜索引擎抓取不到导航
示例(安全可行的 JS 内联):
<script type="text/javascript">
const headerHTML = `<header><nav><ul><li><a href="/>Home</a></li></ul></nav></header>`;
document.body.insertAdjacentHTML('afterbegin', headerHTML);
</script>
⚠️ 注意:这段代码必须放在 <body> 开始后、主内容前,且 headerHTML 必须是字符串字面量,不能走网络请求。
哪些“看似复用”其实违背 DRY 本质
DRY 不是“看起来没重复”,而是“知识源唯一”。下面这些做法看似省事,实则让逻辑散落、修改风险翻倍:
- 用 CSS
content: url(logo.svg)替代<img src="logo.svg">—— 图片路径分散在 CSS 里,无法统一管理尺寸/alt/响应式 - 把导航链接写死在 JS 数组里,再用
forEach渲染到每个页面 —— 导航结构变成 JS 逻辑,HTML 源码无语义,爬虫看不到 - 用
data-*属性存重复文案(如data-footer-text="© 2026"),再 JS 注入 —— 文案脱离 HTML 结构,翻译、审计、自动化测试全失效
真正 DRY 的标志,是打开任意一个生成后的 HTML 文件,它本身就是完整、自包含、无需外部 JS/CSS 就能正确呈现的文档——而所有重复部分,只在一个地方定义、一处修改、全局生效。



















