Apache 通过 mod_headers 模块在反向代理中动态重写后端响应头,支持条件化、环境变量触发及表达式计算;需启用模块、使用 late 模式、配合 ProxyPass,在 Location/Proxy 块中配置 add/set/unset/append 等指令,并注意与 mod_deflate 协同时清理 Content-Encoding 和 Content-Length。

Apache 中对后端响应 Header 的动态重写,核心靠 mod_headers 模块配合反向代理(mod_proxy)使用。它不依赖 Lua 或外部脚本,原生支持条件化、可编程的 Header 修改,且在 ProxyPass 场景下稳定可靠。
启用 mod_headers 并确认作用时机
确保模块已加载:a2enmod headers(Debian/Ubuntu)或取消 mod_headers.so 注释(RHEL/CentOS)。关键点在于:ResponseHeader 指令默认是 late 模式——即在响应即将发出前执行,此时后端响应已完整接收,Header 可安全覆盖或追加。
- 避免用
early关键字处理响应头,它在请求初期运行,后端 Header 尚未生成,无效 - 若需基于请求特征(如用户 IP、路径)做差异化重写,可用
SetEnvIf或RewriteRule [E]设置环境变量,再在Header指令中用env=xxx条件触发
常用 Header 重写操作与典型场景
所有操作均写在 、 或虚拟主机配置块内,作用范围必须覆盖代理路径。
-
添加新头:例如注入调试标识
Header add X-Backend "Tomcat-8" -
覆盖已有头:例如统一设置 CORS 允许来源
Header set Access-Control-Allow-Origin "https://example.com" -
删除危险头:如移除后端暴露的
Server或X-Powered-By:Header unset Server、Header unset X-Powered-By -
条件追加:例如仅对 JSON 响应加 Vary 头:
Header append Vary Accept-Encoding "expr=%{CONTENT_TYPE} =~ m#^application/json#"
与 mod_deflate 配合时的头部清理要点
当启用代理层压缩(SetOutputFilter DEFLATE)时,后端返回的原始 Header 往往与压缩逻辑冲突,必须人工干预:
- 强制清除后端设的
Content-Encoding,否则 Apache 不会再压缩:Header unset Content-Encoding - 删除过期的
Content-Length(压缩后长度变化,Apache 会自动重算):Header unset Content-Length - 补全协商头,确保浏览器正确缓存压缩/未压缩版本:
Header append Vary Accept-Encoding
进阶:用表达式实现动态值注入
Apache 2.4+ 支持 expr= 语法,在 Header 值中嵌入变量或逻辑结果:
- 记录真实客户端 IP:
Header set X-Real-IP "%{REMOTE_ADDR}e" - 根据后端响应状态码差异化设置:
Header set Retry-After "30" "expr=%{REQUEST_STATUS} == 503" - 拼接多个变量:
Header set X-Trace-ID "%{env:UNIQUE_ID}e-%{env:HTTP_X_REQUEST_ID}e"











