nginx可通过sub_filter指令结合正则、变量与map实现响应体按需重写,需禁用gzip、设置sub_filter_types、避免缓存污染并注意json转义与content-length自动修正。

可以利用 Nginx 的 sub_filter 指令结合正则匹配与变量控制,实现对后端响应体(HTML、JSON 等文本内容)的按需重写。关键在于精准控制触发条件、避免破坏原始格式,并注意编码与缓存兼容性。
启用 sub_filter 并设置基础重写规则
Nginx 默认不修改响应体,需显式开启 sub_filter。它仅作用于响应体中的文本内容(text/html、application/json 等),且要求后端返回内容未被压缩(即禁用 gzip 或确保 sub_filter 在解压后生效)。
- 在
location块中启用:添加sub_filter_once off;(允许多次替换)或on(仅首次匹配) - 基本语法:
sub_filter "原文本" "新文本";,支持变量如$arg_env或$host - 示例:将后端返回的 API 地址从
/api/v1改为/proxy/api/v1:sub_filter '/api/v1' '/proxy/api/v1';
按请求参数或 Header 动态控制重写逻辑
通过 map 指令预定义开关变量,再结合 sub_filter 的条件启用,实现“按需”——比如仅对带 ?debug=1 的请求重写前端资源路径。
- 在
http块中定义映射:map $arg_debug $enable_rewrite { default ""; "1" "on"; } - 在
location中使用:sub_filter 'https://cdn.example.com' 'https://$host/cdn';<br> sub_filter_once off;<br> sub_filter_last_modified off;
- 注意:
sub_filter不支持直接写 if 判断,必须靠map+ 变量间接控制是否生效(例如配合add_header X-Rewrite-Status $enable_rewrite;辅助调试)
安全处理 JSON 响应与特殊字符
重写 JSON 时极易因引号、斜杠、编码不一致导致格式损坏。推荐只替换明确字段值(如 URL 字段),避免模糊匹配。
- 确保后端返回
Content-Type: application/json; charset=utf-8,并在 Nginx 中显式声明:sub_filter_types application/json; - 转义特殊字符:Nginx 的
sub_filter不自动转义,若替换内容含双引号,需手动写成\"(在配置文件中用反斜杠转义) - 更稳妥做法:用
sub_filter替换固定前缀,如把"url":"http://old/→"url":"https://new/,避免跨字段误匹配
规避常见陷阱:编码、缓存与响应头
重写失败常因底层机制被忽略。以下三点必须检查:
-
禁用 gzip 传输编码:若后端启用了
gzip,Nginx 默认无法对压缩流做sub_filter;应在 proxy 配置中加gzip off;或确保上游不压缩文本响应 -
修正 Content-Length:重写会改变响应体长度,Nginx 会自动重算并覆盖原头,但若启用
proxy_buffering off,可能失效;建议保持 buffering 开启 -
避免缓存污染:被重写的响应若被 CDN 或浏览器缓存,会导致不同用户看到混杂内容;应添加
add_header Cache-Control "no-cache, must-revalidate";或基于重写条件设置差异化缓存键











