nginx的sub_filter模块支持在代理响应返回前对html等内容进行实时字符串替换,仅支持区分大小写的纯字符串匹配,需通过sub_filter_types显式指定mime类型,配合sub_filter_once、sub_filter_last_modified等指令精细控制替换行为。

Nginx 的 sub_filter 模块可用于在代理响应返回客户端前,对 HTML 内容进行实时字符串替换,常用于修改静态资源路径、注入 JS/CSS、重写链接等场景。它工作在响应体流式处理阶段,轻量高效,但需注意匹配范围和编码限制。
启用 sub_filter 并配置基础替换规则
确保 Nginx 已编译包含 --with-http_sub_module(主流发行版通常默认开启)。在 location 块中使用 sub_filter 指令定义替换对,配合 sub_filter_types 指定生效的 MIME 类型:
- 默认只作用于
text/html,若需处理application/json或自定义类型,必须显式添加,例如:sub_filter_types text/html text/css application/javascript; - 替换支持正则?不支持 ——
sub_filter是纯字符串匹配(区分大小写),如需更灵活处理,需结合sub_filter_once off多次替换或改用第三方模块(如nginx-substitutions-filter) - 示例:将后端返回的
/static/路径统一改为/cdn/sub_filter '/static/' '/cdn/';<br>sub_filter_types text/html text/css application/javascript;
控制替换行为与作用范围
sub_filter 提供多个指令精细控制替换逻辑:
-
sub_filter_once on/off:默认为on,仅替换每行首次匹配;设为off可全局替换所有出现位置(适合批量修正 URL) -
sub_filter_last_modified on:启用后,Nginx 会移除响应头中的Last-Modified,避免因内容被修改导致缓存校验失败 -
sub_filter_recursive on:开启后支持嵌套替换(即替换结果中再触发新匹配),但需谨慎使用,可能引发无限循环 - 注意:替换发生在 gzip 解压之后、压缩之前,因此无需解压响应即可生效;但若后端已返回 gzip 编码且 Nginx 未解压(如未配
gunzip on),则sub_filter不会生效
配合 proxy_pass 实现动态内容改写
典型代理场景下,需确保响应体完整可读,避免流式截断影响替换效果:
- 关闭缓冲(可选):
proxy_buffering off;防止 Nginx 缓冲整个响应再处理,提升实时性(但可能增加延迟) - 强制解压 gzip:
gunzip on;确保即使后端返回 gzip 响应,Nginx 也会先解压再执行sub_filter - 设置响应头兼容性:
sub_filter 'charset=utf-8' 'charset=gbk';可用于调整字符集声明(注意实际内容编码需同步匹配) - 常见陷阱:若 HTML 中存在注释、JS 字符串或属性值内含目标字符串,
sub_filter无法识别上下文,会无差别替换 —— 建议用唯一标识符(如data-sub-replace-src)降低误替风险
调试与验证技巧
替换失效时,优先检查响应流程是否完整经过 sub_filter:
- 用
curl -I查看响应头是否含Content-Encoding: gzip,若有且未启用gunzip on,替换必然跳过 - 临时添加
add_header X-Sub-Filtered "true";到 location,确认配置被加载并执行 - 用
curl -s http://your-domain/ | grep -o "目标关键词"直接验证输出结果,比浏览器更可靠(避开缓存、JS 渲染干扰) - 日志中不会记录替换动作,但可通过
error_log ... debug;开启 debug 日志观察子请求和过滤流程(生产环境慎用)
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











