nginx 的 subs_filter 模块可动态替换响应体文本,需手动编译启用;支持全局/正则替换、变量引用及多指令链式处理,但不作用于 gzip 压缩内容且不跨行匹配。

通过 Nginx 的 subs_filter 模块可以动态替换响应体中的文本内容,适用于在不修改源文件的前提下,对 HTML、JS、CSS 等静态文件做运行时注入或变量替换(比如插入环境标识、CDN 域名、版本号等)。但需注意:subs_filter 是第三方模块,Nginx 官方默认不包含,必须手动编译启用。
确认 subs_filter 模块已启用
执行以下命令检查是否已加载模块:
nginx -V 2>&1 | grep -o with-http-substitutions-module
若无输出,说明未编译该模块。需下载 ngx_http_substitutions_filter_module,并在编译 Nginx 时添加:--add-module=/path/to/ngx_http_substitutions_filter_module
基础用法:替换 HTML 中的字符串
在 location 块中配置,例如将页面中所有 http://localhost:8080 替换为当前域名:
location / {
alias /var/www/html/;
subs_filter 'http://localhost:8080' '$scheme://$host' g;
subs_filter_types text/html text/css application/javascript;
}
-
g表示全局替换(同 sed 的 g 标志);不加则只替换第一个匹配项 -
subs_filter_types必须显式声明 MIME 类型,否则仅对text/html生效 - 支持变量(如
$host、$scheme),但不能在正则模式中直接引用变量(见下条)
进阶用法:正则匹配 + 多次替换
启用正则需加 r 标志,并用 PCRE 语法。例如把所有内联 JS 中的 API_BASE = "xxx" 动态替换成真实地址:
location / {
alias /var/www/html/;
subs_filter 'API_BASE\s*=\s*"[^"]*"' 'API_BASE = "https://api.example.com/v1"' gr;
subs_filter_types text/html application/javascript;
}
-
gr表示全局 + 正则 - 正则中不能直接写
$host等变量,但可通过 Nginx 变量拼接字符串后传入(需配合set和map预处理) - 多次
subs_filter指令按书写顺序依次执行,可用于链式替换
注意事项与常见问题
- subs_filter 不作用于 gzip 压缩后的响应 —— 必须在压缩前处理,因此要确保
gzip off或将subs_filter放在gzip模块之前(通常默认满足) - 不支持跨行匹配(PCRE 默认单行模式),复杂结构建议用服务端模板或构建时处理
- 替换发生在响应体生成后、发送前,对性能有轻微影响,高并发场景慎用于大文件
- 若替换后页面乱码,请检查源文件编码(推荐 UTF-8)并确认
charset utf-8;已设置











