Nginx SSI(Server Side Includes)
一句话总结: SSI 让 Nginx 在返回静态 HTML 之前,先在服务端把 HTML 里的特定指令替换成动态内容,类似"简易版 PHP include"。
核心原理
用户请求 → Nginx 读取 .html 文件 → 遇到 SSI 指令 → 执行替换 → 返回最终 HTML``
它不是完整的编程语言,只是一组 HTML 注释形式的指令,Nginx 识别后做简单处理。
常用指令
| 指令 | 作用 | 示例 |
|---|---|---|
include |
包含另一个文件 | <!--#include file="header.html" --> |
echo |
输出变量(日期、环境变量等) | <!--#echo var="DATE_LOCAL" --> |
set |
设置自定义变量 | <!--#set var="name" value="World" --> |
if/elif/else/endif |
条件判断 | <!--#if expr="$name = World" -->Hi<!--#endif --> |
exec |
执行系统命令 | <!--#exec cmd="date" --> |
config |
配置时间格式等 | <!--#config timefmt="%Y-%m-%d" --> |
flastmod |
输出文件最后修改时间 | <!--#flastmod file="index.html" --> |
printenv |
输出环境变量 | <!--#printenv var="REMOTE_ADDR" --> |
配置方式
# nginx
location / {
ssi on; # 开启 SSI
ssi_silent_errors on; # 出错时静默(不返回 500)
ssi_types text/html; # 指定哪些 MIME 类型解析 SSI
ssi_value_length 256; # 变量值最大长度
}
实际使用示例
典型使用场景
| 场景 | 说明 |
|---|---|
| 公共页头/页脚 | 多个静态页面共用 header、footer,不用手动复制 |
| 显示动态时间/IP | 纯静态站点也能显示"最后更新时间" |
| 简单条件内容 | 根据变量显示不同内容(但逻辑很弱) |
局限性(很重要)
| 问题 | 说明 |
|---|---|
| 性能差 | 每个请求都要解析 SSI 指令,高并发下明显拖累 |
| 功能弱 | 没有循环、没有数组、没有真正的逻辑,复杂需求做不了 |
| 已过时 | 现在基本被 SSI 模板引擎(如 Liquid)、后端渲染(PHP/Node)替代 |
| 仅限 HTML | 只对指定 MIME 类型生效,CSS/JS 里的 SSI 不会被解析 |
什么时候该用?
✅ 纯静态站点,只需要嵌入公共片段、显示时间
❌ 需要复杂逻辑 → 用后端语言
❌ 高流量站点 → 用缓存或构建时生成(SSG)
简单说:SSI 是 Nginx 给纯静态网站留的一个"小后门",够用但别依赖。
SSI 的 include 确实能实现"把组件拆出来、按需引入"的效果:
React/Vue 的 <Header /> ≈ SSI 的 <!--#include file="header.html" -->
是的,但只是最原始的版本。
对比一下就清楚了
| 能力 | SSI include | 现代组件(React/Vue) |
|---|---|---|
| 拆分公共部分 | ✅ 可以 | ✅ 可以 |
| 多页面复用 | ✅ 可以 | ✅ 可以 |
| 传参(props) | ❌ 不行 | ✅ 可以 |
| 条件渲染 | ⚠️ 极弱(if/else) | ✅ 完全支持 |
| 循环列表 | ❌ 不行 | ✅ 可以 |
| 状态管理 | ❌ 没有 | ✅ 有 |
| 交互响应 | ❌ 没有(纯服务端) | ✅ 有 |
| 缓存友好 | ⚠️ 每次请求都解析 | ✅ 虚拟DOM diff |
所以本质上
SSI = 服务端的字符串拼接,每次请求把碎片拼成完整 HTML 返给浏览器。
它能做到的"组件化":
<!-- header.html -->
<nav>...</nav>
<!-- footer.html -->
<footer>...</footer>
<!-- index.html -->
<!--#include file="header.html" -->
<main>页面内容</main>
<!--#include file="footer.html" -->
这跟 React 里把 <Header /> 和 <Footer /> 抽成组件,思路完全一样,只是实现方式是几十年前的技术。
一句话
SSI 能实现"静态组件引入",但没有交互、没有状态,本质是服务端的 include,不是真正的组件化。够用,但别指望它能替代任何现代框架。