apache中mod_headers配置cache-control的核心是透传、补充和安全兜底,而非从零设计缓存策略;需先启用模块,再按静态资源、html、api分层设置,并禁用mod_expires以避免冲突。

Apache 的 mod_headers 不是用来“从零设计”缓存策略的,而是帮你把 Java(或其他后端)已设的 Cache-Control 头执行得更准、更稳、更安全——重点在透传、补充和兜底,不是越俎代庖。
先确认模块已启用,避免 500 错误
很多 Apache 默认不加载 mod_headers,直接写 Header 指令会报错。别跳过这步:
- 运行 apachectl -M | grep headers,有输出才说明已启用
- 没输出?Debian/Ubuntu 执行 a2enmod headers;CentOS/RHEL 编辑 httpd.conf,取消 #LoadModule headers_module modules/mod_headers.so 的注释
- 改完记得重启:systemctl restart apache2 或 apachectl graceful
按资源类型分层设置 Cache-Control
用
-
静态资源(JS/CSS/图片/字体):带版本号或哈希时可放心长缓存
<filesmatch><br> Header set Cache-Control "public, max-age=31536000, immutable"<br></filesmatch>
-
HTML 页面:禁止强缓存,防止用户看到过期内容
<filesmatch><br> Header set Cache-Control "no-cache, no-store, must-revalidate"<br></filesmatch>
-
API 接口(如 /api/ 开头):按敏感程度区分
<locationmatch><br> Header set Cache-Control "private, no-store"<br></locationmatch>
做安全兜底,防遗漏、防误缓存
后端可能漏设头,或用户带 Cookie 时不该被代理缓存——Apache 可补位,但要加条件:
- 对未设 Cache-Control 的响应加默认策略(仅限静态目录):
SetEnvIfNoCase Content-Type "^(text/css|image/)" need_cache_header<br>Header always set Cache-Control "public, max-age=31536000, immutable" env=need_cache_header
- 当请求含 Cookie 时,强制把 public 改为 private:
Header edit Cache-Control "(?i)^public" "private" expr=%{HTTP_COOKIE} != "" - 禁用 mod_expires:它生成的 Expires 头和 Cache-Control 冲突,统一用后者更可靠
验证是否真正生效
配置写完不等于生效,必须逐层检查:
- 用 curl -I https://yoursite.com/app.js 看原始响应头
- 打开浏览器开发者工具 → Network → 查看具体资源的响应头,注意是否出现多条 Cache-Control(说明被重复设置)
- 确认后端(如 Spring Filter 或 Servlet)没有覆盖头——尤其检查是否用了 Header always set(普通 Header set 在已有头时不会覆盖)











