浏览器缓存命中需通过DevTools Network面板观察响应状态码(304表示命中)、响应头(Cache-Control、ETag/Last-Modified)及Size字段(“from disk/memory cache”),而非$upstream_cache_status;务必关闭Disable cache并排除no-store/no-cache等干扰。

直接用浏览器开发者工具验证 Nginx 浏览器缓存命中,核心是看响应头中的 Cache-Control、ETag、Last-Modified 和实际网络行为(是否发起请求、是否 304),而不是看 Nginx 的 $upstream_cache_status——后者只反映 Nginx 代理缓存(后端缓存)状态,和浏览器本地缓存无关。
确认浏览器是否真的复用本地缓存
在 DevTools 的 Network 面板中操作:
- 打开 Disable cache(右上角齿轮 → 勾选 “Disable cache”)——先关掉它,确保后续测试不受干扰
- 刷新页面或重发请求,观察该资源的响应状态码:
→ 若为 200 OK 且响应体完整(Size 列显示 KB 数),说明是首次加载或强制重新获取
→ 若为 304 Not Modified,说明浏览器发送了带If-None-Match或If-Modified-Since的条件请求,服务端校验后确认内容未变,返回空响应体(Size 显示 “from disk cache” 或 “from memory cache”),即浏览器缓存命中 - 再刷新一次(仍保持 Disable cache 关闭),若仍是 304,说明缓存策略生效且未过期;若变成 200,则可能是 max-age 已到或资源被主动清除
检查关键响应头是否符合预期
点击对应请求 → Headers 标签页 → Response Headers 区域,重点核对:
-
Cache-Control:例如
public, max-age=3600表示可被浏览器/中间代理缓存 1 小时;immutable表示内容不可变,支持跳过协商验证 - Expires:HTTP/1.0 兼容字段,应与 Cache-Control 逻辑一致(优先级低于 max-age)
- ETag 或 Last-Modified:必须存在其一,否则浏览器无法发起条件请求,也就无法触发 304
-
Vary:如
Vary: User-Agent,表示缓存需按该头区分;若值为*,多数浏览器会直接不缓存
排除常见干扰项
以下情况会导致看似“没命中”,实则不是配置问题:
- 地址栏直接输入 URL 或点击链接访问:浏览器通常不走协商缓存,而是检查 max-age 是否有效;只有 F5 刷新或前进/后退才更倾向发条件请求
- DevTools 打开状态下默认启用 “Disable cache” —— 务必手动关闭它,否则所有请求都绕过本地缓存
- 响应头含
Cache-Control: no-store或no-cache(无 max-age):浏览器不会存储,每次都是 200 - HTTPS 页面加载 HTTP 资源(混合内容):现代浏览器会阻止并标记为 failed,自然无缓存行为
快速验证技巧(命令行辅助)
用 curl 模拟浏览器行为,比反复刷页面更可控:
- 首次请求,记录 ETag:
curl -I https://yoursite.com/app.js | grep ETag - 第二次请求,带上 If-None-Match:
curl -I -H "If-None-Match: \"abc123\"" https://yoursite.com/app.js
→ 返回304 Not Modified即成功;返回200则说明服务端未正确响应协商 - 加
-w "\n%{http_code}\n"可直接输出状态码,适合脚本批量验证


















