nginx的sub_filter指令可对反向代理响应体中的文本进行动态字符串替换,适用于修正硬编码资源路径,需配置sub_filter_types指定mime类型、sub_filter_once off启用全局替换,并确保响应未压缩且启用输出缓冲。

使用 Nginx 的 sub_filter 指令可以在反向代理响应体中动态替换文本,适用于修正 HTML 中硬编码的绝对资源路径(如 http://old-domain.com/static/ → /static/ 或 https://new-domain.com/static/),无需修改后端代码。
启用 sub_filter 基础配置
sub_filter 默认只处理 text/html 类型响应,且仅对响应体生效(不修改响应头、不处理二进制内容)。需配合 sub_filter_once off(全局替换)或 on(仅首处),并确保 sub_filter_types 包含实际返回的 MIME 类型(如 text/css、application/javascript)。
- 必须开启
proxy_buffering on(默认开启),否则流式响应无法被完整捕获替换 - 若后端返回
Content-Encoding: gzip,需先解压再替换——推荐在 proxy 层关闭 gzip 压缩(proxy_set_header Accept-Encoding ""),或用gunzip on模块(需编译支持) - 替换字符串区分大小写;正则不支持,只能字面匹配
修正静态资源 URL 的典型场景
常见需替换的内容包括:<link href="http://a.com/css/app.css">、<script src="http://a.com/js/bundle.js"></script>、url(http://a.com/img/logo.png)(CSS 中)、background: url('http://a.com/bg.jpg') 等。
- 将第三方域名统一替换为相对路径:
sub_filter 'http://legacy.example.com/' '/'; - 替换为当前请求域名:
sub_filter 'http://legacy.example.com/' '$scheme://$host/';(注意:变量仅在sub_filter值中支持部分内置变量,$scheme和$host可用,但需确认 Nginx 版本 ≥ 1.9.4) - 批量替换不同协议/端口:
sub_filter 'http://api.example.com:8080/' '/api/';,可配多条sub_filter指令
规避常见陷阱
替换失败往往不是语法问题,而是响应未被正确捕获或匹配不到原始字符串:
- 检查响应是否带
Content-Encoding: gzip—— 若有,加proxy_set_header Accept-Encoding ""; gunzip on;(后者需模块支持) - 确认响应头
Content-Type在sub_filter_types列表中,例如:sub_filter_types text/html text/css application/javascript; - HTML 中 URL 可能被转义(如
"http://...)或换行截断,建议后端输出时避免跨行写 URL,或用更宽松的模式(如分段替换sub_filter 'src="http://' 'src="/';) - 替换后可能引入双斜杠(如
//static/),可用两次替换或前端适配
完整示例配置
以下配置实现代理时将所有 http://backend.example.com/ 替换为当前协议+主机名,并支持 CSS/JS 文件中的 URL:
location / {
proxy_pass https://backend.example.com;
proxy_set_header Host backend.example.com;
proxy_set_header Accept-Encoding "";
<pre class="brush:php;toolbar:false;"># 启用解压(若后端压缩)
gunzip on;
# 允许替换 HTML/CSS/JS 中的 URL
sub_filter_types text/html text/css application/javascript;
sub_filter 'http://backend.example.com/' '$scheme://$host/';
sub_filter 'https://backend.example.com/' '$scheme://$host/';
sub_filter_once off;
# 防止缓存污染(可选)
proxy_cache_bypass $http_upgrade;}
注意:$scheme://$host/ 在 HTTP/HTTPS 混合场景下自动适配,但若 Nginx 前有 TLS 终结设备(如 CDN),需确保 $scheme 正确(可通过 map 指令根据 X-Forwarded-Proto 重设)。










