max-age是浏览器判断缓存是否过期的核心依据,以秒为单位的相对时间,从响应被接收时刻起算,优先级高于expires;max-age=0和no-cache均跳过强缓存但机制不同,前者是过期后协商,后者是强制验证。

Cache-Control 的 max-age 是核心判断依据
浏览器不靠猜,也不靠服务器时间戳比对,而是严格按 Cache-Control 响应头里的 max-age 值计算缓存是否过期。这个值是资源被缓存那一刻起、向未来的秒数偏移量。
例如响应头含 Cache-Control: max-age=3600,浏览器在收到响应的瞬间就记下“此资源可放心用 1 小时”,之后每次访问都拿当前时间减去缓存写入时间,看是否超过 3600 秒。
-
max-age存在时,Expires被完全忽略——哪怕它写的是未来一年,浏览器也当没看见 - 若响应中既无
Cache-Control也无Expires,浏览器默认不缓存该响应(或按启发式规则处理,但不可靠) - 客户端系统时间不准不影响判断:因为
max-age是相对值,不依赖绝对时间同步
max-age=0 和 no-cache 都会跳过强缓存,但机制不同
两者都会让浏览器放弃直接读缓存,转而发条件请求,但触发路径和语义完全不同:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
-
max-age=0属于强缓存过期——资源还在磁盘里,只是“有效期归零”,下次请求自动走协商流程(如带If-None-Match) -
no-cache是强制验证指令——哪怕缓存刚写入 1 毫秒,也必须和服务端确认有效性,不考虑“是否过期”这一步 - 实际表现相似(都发条件请求),但服务端日志里看到的请求头可能不同:
max-age=0可能只带If-None-Match,而no-cache通常伴随完整验证头
Last-Modified 和 ETag 不参与“是否过期”判断
这两个字段根本不在过期判定链路上,它们只在协商缓存阶段起作用。也就是说:
- 浏览器看到
Last-Modified: Tue, 13 Oct 2026 08:45:00 GMT,不会拿它跟当前时间比大小来决定是否用缓存 - 它只会在强缓存失效后,作为请求头
If-Modified-Since发出去,由服务器决定是否返回304 -
ETag同理:它不参与本地过期计算,只用于If-None-Match校验;且校验精度高于Last-Modified(内容不变但修改时间变,ETag 仍可命中)
开发调试时最容易误判的点
你在 DevTools Network 面板看到 200 from memory cache 或 200 from disk cache,说明强缓存生效;看到 304,说明强缓存已过期、协商成功;看到 200(无 from cache)且响应体完整,说明协商失败或未配置协商缓存。
- 禁用缓存调试时,Chrome 的 “Disable cache” 开关只影响普通页面加载,不影响 F5 刷新行为(F5 仍可能发条件请求)
- Service Worker 拦截请求后,它自己控制缓存逻辑,此时 HTTP 缓存头可能被绕过——得看 SW 代码里是否调用了
cache.match()或fetch() - CDN 缓存层(如 Cloudflare)有自己的
Cache-Control解析逻辑,可能覆盖源站头,导致你本地测试结果和线上不一致
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










