要让 mod_substitute 真正修改动态输出内容,必须启用 substitute 和 filter 两模块,通过 AddOutputFilterByType 显式注册 MIME 类型,并在 LocationMatch 或 Directory 块内按顺序配置转义正确的 Substitute 指令,同时避免压缩干扰。

要让 mod_substitute 真正修改动态输出内容,关键不是写一条替换指令,而是构建一条可触发、可匹配、不被跳过的处理链。它对配置顺序、模块依赖和响应类型极其敏感,缺一环就完全静默失效。
必须启用并串联两个基础模块
mod_substitute 无法独立工作,必须与 mod_filter 配合才能把替换规则挂进响应流:
- 在 Debian/Ubuntu 上执行:
a2enmod substitute filter,然后重启 Apache - 若手动配置,需确保 httpd.conf 或 mods-enabled 中包含两行:
LoadModule substitute_module modules/mod_substitute.soLoadModule filter_module modules/mod_filter.so - 仅启用 substitute 模块而忽略 filter,所有 Substitute 指令都不会执行
必须显式注册 MIME 类型过滤链
Apache 不会自动对响应体应用替换,必须用 AddOutputFilterByType 明确告诉它“对哪些类型的内容启用 SUBSTITUTE”:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 只处理 HTML 页面:
AddOutputFilterByType SUBSTITUTE text/html - 处理 JSON 接口(如用户数据):
AddOutputFilterByType SUBSTITUTE application/json - 注意:后端返回
Content-Type: application/json; charset=utf-8时,Apache 只认application/json主类型,带分号参数的写法会被忽略 - 该指令必须出现在 LocationMatch 或 Directory 块内,且位置要在 Substitute 指令之前
写能真正生效的替换规则
规则语法看似简单,但符号转义、分隔符选择和标志位设置稍有偏差就会匹配失败或报错:
- 用
s#原内容#新内容#gi格式,推荐 # 或 | 作分隔符,避免斜杠冲突 - JSON 中双引号和反斜杠必须转义,例如:
Substitute "s#\"phone\":\"[0-9]{11}\"#\"phone\":\"****1234\"#g" - Apache 不支持
\d,须写成[0-9];不支持跨行匹配,默认点号.不匹配换行符 - 加
n标志可启用单行模式(防止点号误跨行),加i忽略大小写,加g全局替换
精准控制作用范围,避免误伤
别把脱敏规则放在全局配置里——既影响性能,又可能破坏非目标接口:
- 用
<LocationMatch "^/api/v1/user/detail$">而非<Location />,防止路径前缀匹配错误 - 一个块内可同时声明多种 MIME 类型:
AddOutputFilterByType SUBSTITUTE text/html application/json - 如果后端返回压缩响应(gzip),mod_substitute 通常无法处理,建议临时关闭:
SetEnv no-gzip 1 - 规则按配置顺序执行,前一条改过的文本会影响后一条匹配,敏感字段替换建议放在最后

















