Nginx 的 sub_filter 指令可对 text/html 响应体做纯字符串替换,需关闭 gzip、配合 sub_filter_once off 和 sub_filter_types 显式指定类型,并通过 href="/xxx" 等边界提升准确性,不支持正则与变量。

使用 Nginx 的 sub_filter 指令可以对响应体内容进行字符串替换,从而在不改动后端代码的前提下,动态修改 HTML 页面中的内部链接。但需注意:它仅作用于文本响应(如 text/html),且默认不支持正则、不递归处理、不解析 HTML 结构——因此适用于简单、可控的替换场景。
启用 sub_filter 并设置基础替换规则
确保已加载 ngx_http_sub_module(通常编译时默认包含)。在 location 块中启用替换:
- 用
sub_filter定义原始字符串与目标字符串,例如将相对路径/about替换为带版本前缀的/v2/about - 必须配合
sub_filter_once off才能替换页面中所有匹配项(默认只替换第一个) - 建议开启
sub_filter_types text/html显式指定 MIME 类型,避免误处理 JS/CSS
精准匹配链接,避免误替换
sub_filter 是纯字符串替换,容易误伤。可通过以下方式提升准确性:
- 利用 HTML 属性边界,例如替换
href="/product"而非裸字符串/product,写成:sub_filter 'href="/product"' 'href="/v2/product"'; - 对多个路径统一处理时,可分多条指令,按顺序执行(Nginx 按配置顺序逐条应用)
- 若需区分协议或域名,可组合使用,如:
sub_filter 'href="https://example.com/blog' 'href="https://cdn.example.com/blog'
配合 if 或 map 实现条件化替换
原生 sub_filter 不支持运行时变量,但可通过间接方式实现“按页面动态替换”:
- 用
map指令根据$request_uri设置自定义变量,再在sub_filter中引用(需搭配set和sub_filter在同一上下文) - 更常用的是:针对不同
location分别配置,例如为/admin/下的页面启用专属替换规则 - 注意:不能在
if块内直接写sub_filter(语法不支持),应改用location匹配 + 内嵌配置
注意事项与常见问题
实际使用中易踩坑,需特别留意:
-
sub_filter对压缩响应(gzip)无效,务必在后端关闭 gzip,或确保 Nginx 在 sub_filter 后再压缩(需启用gzip_vary on并谨慎测试) - 响应头需含
Vary: Accept-Encoding,否则缓存可能返回未替换的内容 - 替换后若导致 HTML 标签错乱(如截断属性值),说明匹配太宽泛,应回退到带引号/标签边界的精确字符串
- 不支持 UTF-8 多字节字符的智能切分,中文路径替换需确认编码一致且无截断风险

















