Apache中动态内容失效策略核心是透传或补充Cache-Control等头,而非自身缓存;需禁用mod_cache默认行为,按路径用Header指令设置no-cache/no-store等策略,并谨慎使用mod_expires兜底。

在 Apache 中配置动态内容的失效策略,核心是不依赖传统缓存头(如 Expires)直接控制动态响应的过期行为,因为动态内容通常由后端脚本(PHP、Python WSGI 等)实时生成,Apache 本身不缓存其输出——除非你显式启用并配置了反向代理缓存(如 mod_cache + mod_proxy_fcgi)或使用外部缓存层(如 Varnish)。所以“动态内容失效策略”实际是指:让 Apache 正确传递或注入 Cache-Control、ETag、Last-Modified 等响应头,交由客户端或中间缓存决定是否复用,同时避免错误地强制缓存不可信的动态结果。
明确动态内容不被 Apache 默认缓存
默认情况下,mod_cache 不缓存来自 CGI、FCGI、PHP-FPM(通过 mod_proxy_fcgi)等动态处理器的响应。这是安全设计:Apache 认为动态响应不可预测。若你没启用 mod_cache,那么所谓“失效策略”其实是后端应用的责任——Apache 只负责透传或补充 HTTP 头。
- 确认 mod_cache 未启用(检查
a2enmod cache cache_disk是否执行过,或查看mods-enabled/目录) - 若已启用且想缓存部分动态接口(如 API 响应),必须用
CacheIgnoreHeaders Set-Cookie并配合CacheKeyBaseURL等精细控制,否则含 Cookie 或 Session 的响应绝不应缓存
用 Header 指令注入标准化缓存指令
对 PHP 或其他 CGI 脚本输出,可在 Apache 配置中统一设置响应头,覆盖后端可能遗漏或错误的 Cache-Control 值。例如,让所有 .php 资源默认不缓存:
<FilesMatch "\.php$">
Header set Cache-Control "no-store, no-cache, must-revalidate, max-age=0"
Header unset ETag
Header unset Last-Modified
</FilesMatch>
若某些动态接口允许短期缓存(如仪表盘数据每 60 秒更新),可按路径区分:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
<Location "/api/v1/stats">
Header set Cache-Control "public, max-age=60, stale-while-revalidate=30"
</Location>
注意:stale-while-revalidate 需客户端支持(现代浏览器基本支持),Apache 本身不执行重验证,只是声明策略。
启用并校验 ETag 和 Last-Modified 支持
动态内容能否高效利用条件请求(If-None-Match / If-Modified-Since),取决于是否提供强校验器。Apache 可自动为静态文件生成 ETag,但对动态内容需后端生成;不过你可以用 Header 指令补全基础时间戳(适用于内容变化频率固定的情况):
- 若后端已输出
Last-Modified,Apache 默认透传;无需额外配置 - 若后端只输出
ETag,确保不带弱校验标识(W/"..."),否则无法用于强验证 - 不建议 Apache 自行计算 ETag(如用
FileETag),它只适用于文件系统资源,对动态响应无意义
结合 mod_expires 设置默认过期逻辑(谨慎使用)
mod_expires 可基于 MIME 类型或扩展名设置 Expires 头,但它对动态内容效果有限,因优先级低于后端设置的 Cache-Control(HTTP/1.1 规范中 Cache-Control 优先级更高)。仅当后端完全不发缓存头时才生效:
ExpiresActive On ExpiresByType text/html "access plus 1 second" ExpiresByType application/json "access plus 30 seconds"
⚠️ 注意:设为 1 秒等同于禁止缓存,但语义不如 no-cache 明确;生产环境更推荐用 Header set Cache-Control 直接控制。

















