DocumentRoot 是静态资源物理路径与 URL 映射的基础,缓存生效需在其作用域内配置 mod_expires 和 mod_headers;必须在 <VirtualHost> 或匹配的 <Directory> 中按 MIME 类型设置 ExpiresByType 与 Cache-Control 头,并验证响应头及浏览器缓存行为。

Apache 的 DocumentRoot 本身不直接参与缓存控制,但它决定了静态资源的物理路径和 URL 映射关系,是缓存策略生效的前提基础。真正起作用的是在 DocumentRoot 所在作用域内(如 <VirtualHost> 或 <Directory>)配置的 mod_expires 和 mod_headers 规则。配得对,静态资源才能按预期被浏览器长期缓存;配错了,哪怕 DocumentRoot 指向正确,缓存也形同虚设。
DocumentRoot 要和缓存规则作用域对齐
缓存指令必须写在能覆盖 DocumentRoot 下文件的位置:
- 推荐写在
<VirtualHost>块内,紧贴DocumentRoot后面或内部<Directory>中 - 若用
<Directory "/var/www/html">(即 DocumentRoot 路径),需确保AllowOverride None改为All或至少Options Indexes FollowSymLinks+AllowOverride FileInfo,否则.htaccess中的缓存规则不生效 - 不要只写在主配置顶部——模块启用可以全局做,但
ExpiresByType这类规则必须落在具体上下文里
按资源类型分层设置过期时间(基于 MIME 类型更可靠)
别只靠文件后缀匹配,优先用 ExpiresByType,它读取响应头里的 Content-Type,避免误判:
- 图片(
image/jpeg,image/png,image/webp)→"access plus 1 year" - CSS / JS(
text/css,application/javascript)→"access plus 1 month"(若文件名带哈希,可升为 1 年) - 字体(
font/woff2)、SVG、ICO →"access plus 1 year" - HTML、PHP 输出(
text/html,application/json)→ 显式禁用:"access plus 0 seconds"或"now" - 补上兜底:
ExpiresDefault "access plus 1 day",防止漏配类型被意外缓存
必须补 Cache-Control 头,仅 Expires 不够用
现代浏览器以 Cache-Control: max-age= 为准,Expires 仅作兼容。在同一个 <VirtualHost> 内加:
<IfModule mod_headers.c>
<FilesMatch "\.(css|js|png|jpg|jpeg|webp|gif|ico|svg|woff2)$">
Header set Cache-Control "public, immutable, max-age=31536000"
</FilesMatch>
<FilesMatch "\.html$">
Header set Cache-Control "no-cache, no-store, must-revalidate"
</FilesMatch>
</IfModule>验证是否真生效,别只看配置
重启 Apache 后,打开 Chrome DevTools → Network → 刷新页面 → 点开一个 style.css 或 logo.png:
- 查看 Response Headers 是否同时出现
Expires(GMT 时间)和Cache-Control - 第二次访问时状态码应为
200 (from memory cache)或304,而非每次都200 OK - 用
curl -I https://yoursite.com/main.js也能快速确认响应头
DocumentRoot 是起点,不是终点。缓存能不能稳稳落地,关键在它后面那一段 <Directory> 或 <VirtualHost> 里的几行 ExpiresByType 和 Header set。


















