sub_filter是nginx官方模块,需编译时显式启用--with-http_sub_module,支持响应体字面替换,但默认仅处理text/html、不支持正则(1.9.4+有限支持)、要求禁用gzip且须配置sub_filter_types和sub_filter_once off才能全局生效。

直接编译启用 ngx_http_sub_module 就能用 sub_filter 做响应体文本替换,它不依赖第三方,是 Nginx 官方模块,但默认不启用——必须在 ./configure 阶段显式加入。
确认是否已内置该模块
运行命令检查:
nginx -V 2>&1 | grep -o with-http-sub-module
若无输出,说明当前 Nginx 未编译该模块,需重新编译。
注意:Alpine Linux 的 nginx:alpine 镜像默认已启用;主流发行版(如 Ubuntu/Debian 的 apt 包)通常也包含,但 CentOS/RHEL 的 yum 包常禁用,不可直接假设存在。
源码编译并启用 sub_module
下载 Nginx 源码后,在 ./configure 中添加 --with-http_sub_module:
- 基础编译示例(含常用模块):
./configure \ --prefix=/usr/local/nginx \ --with-http_ssl_module \ --with-http_gzip_static_module \ --with-http_sub_module \ --with-http_realip_module
- 执行
make && sudo make install - 验证安装:
/usr/local/nginx/sbin/nginx -t,再运行nginx -V确认输出含with-http-sub-module
配置 sub_filter 实现替换
模块启用后,即可在 location 或 server 块中使用指令。关键点有三个:
-
必须指定生效的 MIME 类型:默认只处理
text/html,JS/CSS/JSON 需手动加进sub_filter_types,例如:sub_filter_types text/html text/css application/javascript application/json; -
控制替换次数:默认仅替换每行首次匹配项;要全局替换(同一行多次出现都换),加
sub_filter_once off; -
响应不能被 gzip 压缩:sub_module 对压缩后的响应体无效。若后端返回
Content-Encoding: gzip,需在 proxy_pass 后加proxy_set_header Accept-Encoding "";或在 upstream 中禁用 gzip 回传。
典型配置示例:
location / {
proxy_pass https://backend;
proxy_set_header Accept-Encoding "";
sub_filter 'https://old.com' 'https://new.com';
sub_filter_once off;
sub_filter_types text/html text/css application/javascript;
}
常见问题与避坑提示
这些细节容易导致替换失效:
-
大小写敏感? ——
sub_filter默认不区分大小写,但匹配行为依赖底层字符串比较逻辑,建议保持原始大小写一致以避免歧义 -
支持正则吗? —— Nginx 1.9.4+ 支持斜杠包围的正则语法,如:
sub_filter /https?:\/\/[^" ]+/ '$scheme://$host';,但需确保sub_filter_once off和类型声明同时存在 -
变量只能用于替换值,不能用于匹配串:可写
sub_filter 'api.example.com' '$host';,但不能写sub_filter '$old_domain' '$new_domain'; -
替换后 Content-Length 可能错乱:Nginx 会自动重写该头,无需手动干预;但若上游已设固定长度且未分块传输,建议启用
chunked_transfer_encoding on;(默认开启)











