Apache的mod_proxy本身不提供响应内容清洗能力,必须依赖mod_substitute或mod_sed模块对响应体进行正则替换;需注意Content-Encoding为gzip时需先解压或禁用压缩,且须显式指定MIME类型以触发清洗。

Apache 的 mod_proxy 本身不提供响应内容清洗能力。它只负责请求转发与响应透传,所有对响应体(如 HTML、JSON、XML)的修改、过滤、注入或重写,必须借助其他模块配合实现。
真正起作用的是 mod_substitute 和 mod_sed —— 它们能在响应流到达客户端前,对响应体内容进行正则匹配与替换。
✅ 必须启用的核心模块
确保以下模块已加载(在 httpd.conf 或 mods-enabled/ 中):
LoadModule substitute_module modules/mod_substitute.so # Apache 2.4.10+ 推荐用更强大的 mod_sed(需额外编译或启用) # LoadModule sed_module modules/mod_sed.so
⚠️ 注意:
mod_substitute默认不处理压缩响应(如 gzip)。若后端返回Content-Encoding: gzip,Apache 不会解压再替换,会导致清洗失效。解决方法见下文。
✅ 基础响应清洗配置(HTML 页面中替换文本)
适用于静态替换,比如把后端返回的 http://internal-api.example.com 换成 /api:
<Location "/app/">
ProxyPass "http://192.168.1.20:8080/"
ProxyPassReverse "/app/"
# 启用内容替换(仅对 text/* 类型生效)
AddOutputFilterByType SUBSTITUTE text/html text/plain text/css text/javascript
# 替换响应体中的敏感 URL(注意正则转义和全局标志 g)
Substitute "s|http://internal-api\.example\.com|/api|g"
Substitute "s|<script src=\"//cdn|<script src=\"/cdn|g"
</Location>-
AddOutputFilterByType SUBSTITUTE ...控制哪些 MIME 类型参与清洗; -
Substitute指令支持 Perl 兼容正则,g表示全局替换; - 若含特殊字符(
./"),需反斜杠转义。
✅ 处理压缩响应(gzip)的正确姿势
后端若开启 gzip,Apache 默认跳过 mod_substitute。两种可靠解法:
方案一:让后端不压缩(推荐)
在 ProxyPass 前清除 Accept-Encoding 请求头,强制后端返回明文:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
RequestHeader unset Accept-Encoding ProxyPass "http://192.168.1.20:8080/"
✅ 简单、稳定、无兼容风险。
方案二:Apache 解压后再清洗(需 mod_deflate)
# 先解压(仅对含 gzip 的响应) SetOutputFilter INFLATE;SUBSTITUTE;DEFLATE AddOutputFilterByType SUBSTITUTE text/html text/json application/json Substitute "s|\"env\":\"dev\"|\"env\":\"prod\"|i"
⚠️ 风险:增加 CPU 开销;若响应未压缩或编码异常,可能出错;DEFLATE 可能破坏二进制内容(如图片、字体),切勿对 */* 或 application/octet-stream 使用。
✅ 清洗 JSON 响应(常见于 API 网关场景)
mod_substitute 支持 application/json,但要注意:
- JSON 是严格格式,正则替换易出错(如字段名重复、嵌套引号);
- 更安全的做法是用
mod_sed(支持多行、更精准上下文匹配),或改用 Nginx +sub_filter/ Lua 脚本。
简易示例(仅适用于扁平 JSON 字段):
AddOutputFilterByType SUBSTITUTE application/json Substitute "s|\"debug\":true|\"debug\":false|i" Substitute "s|\"version\":\"[^\"]*\"|\"version\":\"2.4.33\"|i"
? 提示:用
i标志忽略大小写;避免跨行匹配——mod_substitute默认按行处理,JSON 若被压缩成单行则可用,否则需mod_sed。
❌ 常见失效原因与避坑提示
- 后端返回
Content-Type: text/html; charset=UTF-8→ 正常匹配;
若返回Content-Type: application/xhtml+xml→mod_substitute默认不处理,需显式添加类型; -
Substitute在<Location>内生效,不能放在<VirtualHost>顶层(除非配合SetOutputFilter); - 替换后响应长度变化,若启用了
Content-Length头,Apache 会自动重算,无需手动干预; - 不要试图用
mod_headers修改响应体——它只能操作响应头。
不复杂但容易忽略。

















