Nginx 的 sub_filter 指令支持对未压缩的 text/html 响应做大小写敏感的静态字符串替换,需关闭 gzip、显式设置 MIME 类型、启用 sub_filter_once off,并可通过 map 配合变量实现环境感知注入。

Nginx 的 sub_filter 指令可用于在响应返回给客户端前,对静态 HTML 内容做简单字符串替换,适合轻量级动态注入(如 CDN 域名替换、环境标识添加、JS/CSS 路径修正等),但不支持正则捕获或复杂逻辑。
启用 sub_filter 的基本前提
必须确保响应是 text/html 类型且未被压缩(gzip/br 压缩会破坏文本匹配);同时需开启 sub_filter_once off 才能全局替换(默认只替换第一个匹配项)。
- 关闭 gzip:在 location 或 server 块中加
gzip off;(若用 gzip_static,则静态 .gz 文件不受影响,但需确保原始 HTML 未被压缩) - 显式设置类型:用
types { text/html html; }确保 .html 响应被识别为 text/html - 启用多处替换:
sub_filter_once off;
基础替换语法与常见写法
sub_filter 是“查找-替换”模式,区分大小写,不支持正则。可链式使用多个 sub_filter 指令(后定义的优先执行)。
- 单次替换:
sub_filter '<title>My Site</title>' '<title>My Site - Prod</title>'; - 路径替换(常用于 CDN):
sub_filter 'src="/static/' 'src="https://cdn.example.com/static/'; - 追加内容(利用空字符串):
sub_filter '</head>' '<script>console.log("env: prod");</script></head>';
配合变量实现轻量“动态”效果
虽然 sub_filter 本身不支持变量,但可通过 Nginx 内置变量(如 $host、$server_addr)结合 sub_filter 实现环境感知替换:
立即学习“前端免费学习笔记(深入)”;
- 定义 map 映射环境:
map $host $env_tag { dev.example.com "DEV"; prod.example.com "PROD"; default "UNK"; } - 在 location 中引用:
sub_filter '<body>' '<body data-env="$env_tag">'; - 注意:变量需在
sub_filter中直接写成$env_tag,Nginx 会自动展开(前提是该变量已定义且作用域可见)
调试与避坑要点
替换失败常见原因是 MIME 类型不匹配、内容被压缩、或 HTML 响应含 BOM/编码异常。
- 用 curl -I 查看响应头:
Content-Type: text/html和Content-Encoding是否为空 - 用 curl -s 不带压缩头测试:
curl -H "Accept-Encoding:" http://localhost/page.html - 避免跨标签匹配(如替换
<p>hello</p>中的hello安全,但替换<p>hello</p><div>world</div>中的</p><div>易因换行/空格失效) - 替换内容含特殊字符(如双引号、$)需用单引号包裹,并对 $ 做转义(
\$)防止变量误解析



















