Nginx的sub_filter指令支持高效字符串替换,适用于文本响应,需配置sub_filter_types和sub_filter_once off以实现全量替换,但不支持正则、跨行、gzip响应及流式传输。

Nginx 的 sub_filter 指令可以在 HTTP 响应体(response body)中做简单、高效的字符串替换,常用于前端资源路径改写、环境标识注入、CDN 域名切换等场景。但要注意:它仅作用于文本响应(如 text/html、text/css、application/javascript),且默认只处理第一个匹配项——要实现“全站内容动态替换”,需合理配置作用范围、启用多匹配和类型匹配。
启用 sub_filter 并覆盖全站响应
在 http 块中全局启用,需结合 sub_filter_types 显式声明支持的 MIME 类型,否则仅对 text/html 生效:
http {
# 允许对常见文本类响应做替换
sub_filter_types text/html text/css application/javascript application/json text/plain;
# 开启全局替换(不止首个匹配)
sub_filter_once off;
<pre class="brush:php;toolbar:false;"># 示例:将所有 http://old.example.com 替换为 https://new.example.com
sub_filter 'http://old.example.com' 'https://new.example.com';
sub_filter 'http://static.old.com' 'https://cdn.new.com';}
⚠️ 注意:sub_filter 是逐行处理的,不支持正则、不跨行匹配,也不解析 HTML 结构,所以不能替代 DOM 操作或服务端模板渲染。
按 location 精确控制替换范围
全局配置易误伤 API 或二进制响应(如图片、字体),推荐在 location 块中按需启用,并关闭无关类型:
- 对 HTML 页面统一注入调试标识:
location / {<br> sub_filter '' '<script>window.ENV="staging"</script>';<br> sub_filter_once off;<br> sub_filter_types text/html;<br>} - 对静态资源 JS/CSS 做 CDN 路径替换:
location ~ \.(js|css)$ {<br> sub_filter 'https://origin.example.com' 'https://www.php.cn/link/ca904c1dfe5c1e4415ce964959278c45';<br> sub_filter_once off;<br> sub_filter_types application/javascript text/css;<br>}
动态替换需配合变量与 map 模块
sub_filter 本身不支持变量插值(如 $host),但可通过 map 预定义替换值,再引用:
map $host $cdn_domain {
default "cdn.example.com";
~^staging\. "cdn.staging.example.com";
~^dev\. "localhost:8080";
}
<p>server {
location / {
sub_filter '<a href="https://www.php.cn/link/ca904c1dfe5c1e4415ce964959278c45">https://www.php.cn/link/ca904c1dfe5c1e4415ce964959278c45</a>' "<a href="https://www.php.cn/link/7611c2ba98f6c400df922115b07c9903">https://www.php.cn/link/7611c2ba98f6c400df922115b07c9903</a>";
sub_filter_once off;
sub_filter_types text/html application/javascript text/css;
}
}</p>
✅ 这样就能根据请求域名自动切换替换目标,实现轻量级“动态”效果。
关键限制与避坑提醒
-
不支持 gzip 响应直接替换:若后端返回了
Content-Encoding: gzip,sub_filter 会失效。必须在 Nginx 中先解压(gzip off;或用gunzip on;模块); -
响应必须有明确 Content-Type:若后端未设类型或设为
application/octet-stream,需用default_type text/html;或add_header强制修正; -
大小写敏感:替换区分大小写,如需忽略,得靠后端输出统一格式,或改用第三方模块(如
ngx_http_substitutions_filter_module); - 不适用于流式响应(streaming):sub_filter 缓存整个响应体,对大文件或长连接 SSE 不友好,慎用于下载页或实时日志接口。
只要响应是文本、未压缩、类型明确,sub_filter 就是零成本、低延迟的全站字符串替换方案。它不是万能的,但在合适场景下足够轻快可靠。










