Nginx sub_filter可动态替换反向代理响应中的URL,需满足:响应为text/html等指定类型、禁用gzip压缩、启用sub_filter_once off、配置在proxy_pass同location块中。

使用 Nginx 的 sub_filter 指令可以在反向代理响应返回给客户端前,动态替换 HTML(或其他文本响应)中的 URL 字符串,从而将后端服务使用的内网地址(如 http://192.168.1.10:8080 或 /api/)替换成对外暴露的公网域名或路径,解决页面加载资源失败、跳转错位等问题。
确保 sub_filter 生效的基本前提
sub_filter 默认只作用于 text/html 类型响应,且需满足以下条件:
- 后端响应头中必须包含
Content-Type: text/html(或匹配你配置的sub_filter_types) - 响应不能被压缩(如 gzip),否则需先解压或禁用压缩:
proxy_set_header Accept-Encoding ""; proxy_http_version 1.1; - 需启用
sub_filter_once off才能替换所有匹配项(默认只替换第一个) -
sub_filter必须写在location块中,且该 location 需为proxy_pass所在上下文
替换内网 IP 或端口为公网域名
假设后端返回的 HTML 中含:<a href="http://192.168.1.10:8080/user">个人中心</a>,而你希望它变成 https://app.example.com/user:
location / {
proxy_pass http://backend_cluster;
proxy_set_header Host $host;
<pre class="brush:php;toolbar:false;"># 关键:替换内网地址为公网地址
sub_filter 'http://192.168.1.10:8080' 'https://app.example.com';
sub_filter 'http://192.168.1.10' 'https://app.example.com';
sub_filter_once off;
sub_filter_types text/html text/css application/javascript;
# 防止 gzip 干扰替换(重要!)
proxy_set_header Accept-Encoding "";
proxy_http_version 1.1;}
处理相对路径与协议相对 URL
若后端使用 //192.168.1.10:8080/api 或 /static/js/app.js 等路径,可分别处理:
- 协议相对链接:
sub_filter '//192.168.1.10:8080' '//app.example.com' - 根路径资源:
sub_filter '/static/' '/static/'(看似无变化?实际用于触发重写逻辑)→ 更推荐用sub_filter '/static/' '/myapp/static/'实现路径前缀修正 - 注意:正斜杠开头的路径是绝对路径,替换时需确保上下文一致(如站点部署在子路径
/myapp/下)
进阶:结合变量实现动态替换(Nginx ≥ 1.9.4)
若需根据请求 Host 或路径动态调整替换目标,可使用变量(需开启 sub_filter_last_modified on 并配合 sub_filter 变量语法):
set $upstream_url "https://$host"; sub_filter 'http://192.168.1.10:8080' $upstream_url;
⚠️ 注意:变量替换仅在较新 Nginx 版本支持,且 sub_filter 中变量不会实时展开(需搭配 sub_filter_last_modified 和缓存控制),生产环境建议优先用静态替换+多 location 分离策略。
不复杂但容易忽略的是响应类型识别和压缩干扰——这两点调不通,sub_filter 就像没装上子弹的枪。确认好 MIME 类型、关掉 gzip、打开全局替换,内网链接就能稳稳“出内网”。

















