Apache mod_proxy需联合mod_deflate与mod_filter实现响应解压后过滤:先由mod_deflate解压gzip响应(2.4.30+需启用SetOutputFilter DEFLATE),再由mod_filter通过Substitute对文本内容正则替换,顺序错误或类型不匹配将导致失败。

Apache 的 mod_proxy 本身不直接处理响应体的解压或内容级过滤,它只负责转发请求和响应。但结合 mod_filter、mod_deflate 和 mod_headers 等模块,可以在反向代理链路中对后端返回的响应数据实现实时解压(如 gzip)后再做内容过滤——关键在于响应流的处理顺序与模块协作机制。
响应解压必须在过滤前完成
后端若返回 Content-Encoding: gzip,Apache 默认不会自动解压;浏览器能解压,但 mod_filter 无法处理压缩后的二进制流。因此需先解压,再过滤:
- ✅ 正确顺序:
mod_deflate(解压) →mod_filter(内容匹配/替换) - ❌ 错误顺序:
mod_filter尝试读 gzip 二进制 → 失败或乱码
启用解压需满足两个前提:
- 后端响应带
Content-Encoding: gzip(或deflate) - Apache 配置中启用
mod_deflate并开启 反向代理解压支持(默认关闭)
# 启用 mod_deflate(确保已加载) LoadModule deflate_module modules/mod_deflate.so # 允许对反向代理响应进行解压(2.4.30+ 支持) <ifmodule deflate_module> # 解压来自后端的 gzip/deflate 响应 SetOutputFilter DEFLATE # 仅对特定 Content-Type 解压(避免破坏图片、PDF等) AddOutputFilterByType DEFLATE text/html text/plain text/css text/javascript application/json application/xml # 关键:允许解压代理响应(默认只处理本地生成内容) DeflateFilterNote Input instream DeflateFilterNote Output outstream DeflateFilterNote Ratio ratio </ifmodule>
⚠️ 注意:
SetOutputFilter DEFLATE对代理响应生效,依赖mod_deflate版本 ≥ 2.4.30。旧版需用mod_ext_filter+ 外部解压工具(不推荐)。
用 mod_filter 实现响应体二次过滤
mod_filter 是 Apache 中唯一支持基于条件动态插入输出过滤器的模块,适合对解压后的文本响应做正则替换、头信息注入、敏感词过滤等。
典型场景:把后端返回的 http://internal-api.example.com 替换为 /api,或注入 <script></script> 安全头。
# 加载必要模块 LoadModule filter_module modules/mod_filter.so LoadModule substitute_module modules/mod_substitute.so # 在虚拟主机或 ProxyPass 后配置 <location> # 确保响应已解压且是文本类型 AddOutputFilterByType SUBSTITUTE text/html text/plain text/css text/javascript application/json # 执行字符串替换(支持 PCRE 正则) Substitute "s|https?://internal-api\.example\.com|/api|ni" Substitute "s||<meta http-equiv='\"Content-Security-Policy\"' content='\"default-src'>|i" </location>
-
Substitute指令作用于mod_filter调度后的输出流,只处理已解压、未编码的纯文本响应体 -
ni表示不区分大小写 + 全局匹配;i表示忽略换行符影响 - 不支持二进制或非 UTF-8 编码内容(如 GBK 页面需先转码或改用
mod_ext_filter)
高级需求:JSON 字段级重写(需 mod_substitute + 正则技巧)
例如后端返回 {"user":{"id":123,"name":"Alice"}},想把 name 统一替换为 ***:
Substitute "s|\"name\"\s*:\s*\"[^\"]*\"|\"name\":\"***\"|g"
⚠️ 局限性:
- JSON 结构复杂时(嵌套、转义引号)正则易出错,不推荐替代应用层处理
- 无语法解析能力,仅字符串层面替换
安全与性能提醒
-
mod_substitute会缓冲整个响应体再处理,大文件(如 >1MB)可能吃光内存,建议配合LimitRequestBody或前置 CDN 过滤 - 避免在
ProxyPass全局路径上无差别启用Substitute,应限定Location或FilesMatch - 若后端已启用
Content-Encoding: br(Brotli),Apache 当前(2.4.x)原生不支持解压,需 Nginx 或应用层处理
不复杂但容易忽略:解压和过滤不是开个模块就自动联动,必须显式控制执行顺序、类型匹配和缓冲行为。











