Apache动态网页缓存验证核心是Last-Modified与ETag配合条件请求,需应用层显式设置真实修改时间或强ETag,禁用默认弱ETag,搭配must-revalidate等Cache-Control指令,并验证304响应是否正确返回。

Apache 对动态网页的缓存验证机制,核心在于让浏览器或中间代理能高效判断“内容是否已更新”,而非每次都重新下载整页。它不依赖简单过期时间(Expires),而是靠 Last-Modified 和 ETag 配合条件请求(If-Modified-Since / If-None-Match)实现轻量级验证。优化关键不是禁用验证,而是让验证更可靠、更一致、更少误判。
确保 Last-Modified 值真实反映内容变更
Apache 默认对静态文件会自动设置 Last-Modified(取文件系统 mtime),但动态页面(如 PHP、JSP、CGI)不会自动提供——必须由应用层显式输出。若遗漏或写错,会导致缓存失效或始终返回 200。
- 在 PHP 中,避免硬编码时间,改用文件或数据源的真实修改时间:
<?php
$mtime = filemtime('/path/to/data.json');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $mtime) . ' GMT');
?> - 对数据库驱动页面,可基于主表最新更新时间生成:
SELECT MAX(updated_at) FROM articles; 并将其转为 HTTP 头 - 禁用 Apache 自动添加的虚假
Last-Modified(尤其在反向代理后):在配置中加Header unset Last-Modified,避免覆盖应用层正确值
合理配置 ETag 以避免弱校验与散列冲突
ETag 是服务器生成的内容指纹,默认由 Apache 基于文件 inode、大小、mtime 组合生成(FileETag INode MTime Size)。这对动态内容完全无效——同一 URL 每次响应内容不同,但 inode/mtime 不变,ETag 就不变,导致缓存永远不更新。
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 对所有动态路径禁用默认 ETag:
<LocationMatch "\.(php|jsp|cgi|pl|py)$">
FileETag None
</LocationMatch> - 如需启用 ETag,应由应用层生成强标识(如内容哈希、版本号、数据摘要):
header('ETag: "' . md5($output_body) . '"');
并确保响应头中Cache-Control包含must-revalidate或明确no-cache策略 - 若使用 mod_cache_disk,确认
CacheIgnoreHeaders ETag已设,防止磁盘缓存错误复用 ETag
配合 Cache-Control 强化验证语义
仅靠验证头不够,必须搭配正确的缓存指令,告诉客户端“何时该验证”“验证失败怎么办”。对动态内容,通常不设长时效,而强调再验证逻辑。
- 推荐组合(适用于内容更新较频繁但非实时的后台页面):
Cache-Control: public, must-revalidate, max-age=0, s-maxage=300
→ 浏览器每次都要验证(max-age=0),CDN 可缓存 5 分钟但必须验证后再返回 - 对用户专属动态页(含 Cookie 或 Session),强制禁止共享缓存:
Cache-Control: private, must-revalidate
并确保Set-Cookie不被缓存(加CacheIgnoreHeaders Set-Cookie) - 避免混用
no-cache和no-store:no-cache允许缓存但强制验证;no-store完全禁止存储——后者会彻底绕过验证机制,失去性能收益
验证机制生效的关键检查点
实际部署后,需确认三方面是否协同工作:
- 浏览器发起第二次请求时,是否携带
If-Modified-Since或If-None-Match头 - 服务器返回是否为
304 Not Modified(而非200 OK),且响应体为空 - 响应头中是否同时存在
Last-Modified+ETag(不推荐共存),或仅保留其一且逻辑自洽 - 用
curl -I http://yoursite/page.php和curl -I -H "If-Modified-Since: [value]" http://yoursite/page.php手动测试

















