sub_filter在网关层实现静态响应关键词动态过滤,本质是字符串级、流式、无上下文替换,需满足模块启用、类型匹配、内容未压缩、边界完整等前提。

用 sub_filter 在网关层做静态响应的关键词动态过滤,本质是字符串级、流式、无上下文的替换,不改后端代码就能生效,但必须满足几个硬性前提:模块启用、类型匹配、内容未压缩、边界完整。它不是正则引擎,也不是 HTML 解析器,所以“怎么写才不白配”比“怎么写才高级”更重要。
确保 sub_filter 模块可用且响应可处理
先确认 Nginx 已编译并启用了 ngx_http_sub_module:
- 运行
nginx -V 2>&1 | grep -o with-http_sub_module,有输出即表示支持 - 检查响应头:用
curl -I http://your-gateway/path查看Content-Type,必须是text/html、text/plain、application/json等明确文本类型;若为application/octet-stream或无Content-Type,sub_filter不触发 - 务必显式设置
sub_filter_types,例如:sub_filter_types text/html text/plain application/json;(默认只认text/html)
让关键词替换真正生效的关键配置
很多配置写了却没效果,问题常出在响应传输环节:
-
禁用压缩:如果后端返回 gzip 内容,
sub_filter默认跳过。最稳妥做法是加gzip off;,或改用gunzip on;(需 Nginx 启用ngx_http_gunzip_module) -
绕过分块编码:
Transfer-Encoding: chunked容易导致关键词被切在块边界而无法匹配。建议后端返回Content-Length,或在 Nginx 中设proxy_buffering on;+ 合理的proxy_buffer_size和proxy_buffers -
启用全局替换:默认
sub_filter_once on只换第一个匹配项,关键词过滤通常需要全部替换,所以加sub_filter_once off; -
忽略大小写?不行——原生不支持:如需大小写无关匹配,得靠多次指令覆盖(比如同时写
sub_filter "ERROR" "***";和sub_filter "error" "***";),或换用第三方模块
典型关键词过滤场景与写法示例
实际中常见需求,直接对应配置即可:
-
脱敏手机号/邮箱:
sub_filter '13812345678' '138****5678';(注意:仅对明文响应有效,JS 动态渲染的内容不处理) -
替换测试环境标识:
sub_filter '<div class="env-badge">DEV</div>' '<div class="env-badge" style="display:none;">DEV</div>';(用样式隐藏比删除更安全) -
批量屏蔽敏感词:按顺序写多条,长词优先防误替:
sub_filter "某品牌A有限公司" "***"; sub_filter "某品牌A" "***"; -
注入通用提示语:
sub_filter '

















