Nginx sub_filter可动态替换JSON响应中的URL,需配置sub_filter_types application/json、关闭gzip、启用proxy_buffering,并用带上下文的正则精准匹配,避免破坏JSON结构。

利用 Nginx 的 sub_filter 指令可以在代理响应返回客户端前,对响应体(response body)进行字符串替换,适用于动态修正 JSON 中的 URL 字段(如 "avatar": "https://origin.com/a.png" → "avatar": "https://cdn.example.com/a.png")。但需注意:它仅工作于文本响应,且默认不处理压缩内容。
确保响应可被 sub_filter 处理
Nginx 默认只对 text/html 类型启用 sub_filter,而 JSON 响应通常为 application/json。需显式启用:
- 添加
sub_filter_types application/json;,允许对 JSON 响应体执行替换 - 关闭响应压缩:
gzip off;或确保上游不返回Content-Encoding: gzip——sub_filter无法解压处理 gzip 内容 - 确认响应未启用流式传输(如
transfer-encoding: chunked本身不影响,但若后端边生成边发、未设Content-Length且未缓冲完整响应,sub_filter可能只处理部分数据);建议配合proxy_buffering on;和合理 buffer 设置
编写精准的 sub_filter 替换规则
JSON 是结构化文本,直接全局替换易出错(如误改字段名或嵌套路径)。推荐策略:
使用约定式提交(Conventional Commits)生成标准化的 Git 提交信息。适用于以下场景: (1) 暂存更改时需要提交信息; (2) 审查 diff 时希望获得结构化摘要; (3) 编写 PR 描述或变更日志(changelog)条目; (4) 用户明确要求“为本次更改编写提交信息”。 该功能会分析已暂存/未暂存的 diff,并生成按类型(type)划分范围的提交信息。
- 用明确上下文锚定目标,例如将
"avatar":"https://api.old.com/替换为"avatar":"https://cdn.new.com/,而非只替换域名 - 启用正则支持(Nginx ≥ 1.9.4):
sub_filter '("avatar":\s*")https://api\.old\.com' '$1https://cdn.new.com'; sub_filter_once off; - 避免跨行匹配 —— 默认
sub_filter不支持多行,若 JSON 被格式化换行(如含\n"avatar"),需确保后端返回紧凑 JSON(minified),或用 Lua 模块处理复杂场景
配合 proxy_pass 完整配置示例
以下是一个安全可用的代理+链接重写片段:
location /api/users {
proxy_pass https://backend-api/;
proxy_set_header Host $host;
<pre class="brush:php;toolbar:false;"># 启用 JSON 替换
sub_filter_types application/json;
sub_filter '("avatar":\s*")https://api\.old\.com' '$1https://cdn.new.com';
sub_filter '("cover":\s*")https://api\.old\.com' '$1https://cdn.new.com';
sub_filter_once off;
# 必须关闭压缩 & 启用缓冲
gzip off;
proxy_buffering on;
proxy_buffers 8 256k;
proxy_busy_buffers_size 512k;
# 防止缓存污染(若使用 proxy_cache,注意 sub_filter 后响应体已变,ETag/Last-Modified 可能失效)
add_header X-Sub-Filtered "true";}
注意事项与替代方案
sub_filter 是轻量级文本替换,不解析 JSON 语法,因此:
- 不校验 JSON 合法性,替换错误可能导致前端解析失败(建议搭配监控响应状态码和 JS 错误日志)
- 无法处理 base64 编码 URL、URL 编码字符(如
%2F)、或字段值含双引号转义(\")的场景 - 高可靠需求建议在应用层统一做 CDN 域名注入(如通过环境变量或配置中心),或用
ngx_http_lua_module+cjson实现安全 JSON 重写

















