启发式缓存是浏览器在无cache-control和expires时,依据date与last-modified时间差的10%自动计算缓存时长的保底策略,属强缓存但优先级最低,命中时显示200(from disk cache);需显式设置缓存头避免意外。

启发式缓存不是“莫名”缓存,而是浏览器在没有明确缓存指令时,主动启用的一套默认保底策略。
它怎么工作的?
当响应头里既没 Cache-Control 也没 Expires,浏览器不会放弃缓存——它会根据已有时间戳“猜”一个合理有效期:
- 取响应头中的 Date(服务器返回时的时间)和 Last-Modified(资源最后修改时间)
- 计算差值:
Date − Last-Modified - 再乘以 10%:缓存时长 = (Date − Last-Modified) × 10%
比如资源是 10 天前修改的(864000 秒),浏览器就可能缓存约 86400 秒(24 小时)。这个值可长可短,完全取决于原始修改间隔。
为什么你“感觉被莫名缓存”?
因为这种缓存不显式声明,开发者容易忽略。你没配任何缓存头,但 Chrome Network 面板里仍看到 200 OK(from disk cache),甚至请求栏显示 Provisional headers are shown —— 这正是启发式缓存生效的标记。
它和强缓存、协商缓存的关系
启发式缓存属于强缓存范畴:命中时完全不发请求,直接读磁盘/内存。但它优先级最低,仅在 Cache-Control 和 Expires 都缺失时才启用。一旦你加了 no-cache 或 max-age=0,它就立即失效。
怎么避免意外缓存?
别依赖“没设头=不缓存”。稳妥做法是显式声明意图:
- 想禁用缓存 → 响应头加
Cache-Control: no-store或no-cache - 想控制缓存时间 → 至少设
Cache-Control: max-age=3600 - 静态资源(JS/CSS)→ 推荐配合文件哈希命名 +
max-age=31536000(1年) - HTML 页面 → 通常设
no-cache或短max-age,确保能及时拉新
不设缓存头 ≠ 不缓存,只是把决定权交给了浏览器的启发逻辑——而它未必符合你的业务预期。











