http缓存
一、为什么要有 HTTP 缓存
目的:减少网络请求,加快加载速度,降低服务器压力,提升用户体验。
本质:浏览器在本地存储资源副本,下次请求时直接复用,或确认是否需要更新。
二、HTTP 缓存体系结构
HTTP 缓存可以分为 强缓存 和 协商缓存 两大类。
1. 强缓存(不用问服务器)
特点:命中时直接用本地副本,不会发请求。
关键字段:
Expires
:HTTP/1.0 的方式,表示绝对过期时间。缺点是受客户端时间影响。Cache-Control: max-age=秒数
:HTTP/1.1 推荐,资源在多少秒内有效。
命中效果:状态码 200 (from disk cache / memory cache)。
2. 协商缓存(需要问服务器)
特点:资源可能过期,但浏览器会带上缓存标识,请求服务器验证是否更新。
关键字段:
Last-Modified
/If-Modified-Since
服务器返回资源最后修改时间。
浏览器下次请求时带上
If-Modified-Since
,服务器对比,如果没改动返回 304 Not Modified。缺点:时间精度秒级,文件内容没变但时间变了也会触发重新加载。
ETag
/If-None-Match
服务器返回文件内容的唯一标识(hash、版本号等)。
浏览器下次请求时带上
If-None-Match
,服务器比对标识是否一致。更精准,但计算和存储有开销。
命中效果:状态码 304 Not Modified,资源走缓存,但请求-响应头仍会交互。
三、缓存策略优先级
浏览器缓存判定流程可以简化为:
是否有强缓存(Expires/Cache-Control)且未过期?
✅ 命中 → 直接用本地副本。
❌ 过期 → 进入协商缓存。
是否有协商缓存标识(ETag/Last-Modified)?
✅ 发送请求,带上标识。
资源没改 → 返回 304,用本地缓存。
资源更新 → 返回 200,替换本地缓存。
❌ 没有标识 → 只能重新请求。
四、常见 Cache-Control 指令
Cache-Control
是 HTTP 缓存的核心,支持多个指令组合:
强缓存相关:
max-age=秒数
:资源在多少秒内新鲜。s-maxage=秒数
:专门给代理服务器缓存用(CDN)。
是否可缓存:
public
:任何地方都可以缓存(浏览器、代理)。private
:只能浏览器缓存,代理不可缓存(如用户信息)。no-store
:彻底禁止缓存(敏感数据)。no-cache
:不是“不要缓存”,而是必须向服务器验证,即进入协商缓存。
缓存行为控制:
must-revalidate
:一旦过期必须去服务器验证。
📌 示例:
Cache-Control: max-age=31536000, public
表示资源缓存 1 年,所有人都能用缓存。
五、缓存位置
浏览器缓存分层存放,命中优先级不同:
Service Worker Cache(最高优先级,开发者可控)
Memory Cache(内存缓存,页面关闭即失效)
Disk Cache(磁盘缓存,长期有效)
Push Cache(HTTP/2 特有,生命周期极短)
六、前端实战应用场景
1. 静态资源(JS/CSS/图片)
文件名带 hash(如
app.abc123.js
)。设置:
Cache-Control: max-age=31536000, immutable
文件更新时 hash 改变,自动失效,永远走强缓存。
2. HTML 文件
HTML 一般不做长期强缓存,因为要随时更新。
设置:
Cache-Control: no-cache
浏览器每次都会请求服务器,但如果内容没变,返回 304。
3. API 数据
视业务而定:
静态数据(如字典表):可长时间缓存。
动态数据(如用户信息):一般
no-cache
或private, max-age=0
。
七、缓存调试方法
Chrome DevTools → Network 面板
看 Status:
200
/200 (from memory cache)
/304
。看 Response Headers:
Cache-Control
、ETag
等。
curl 命令模拟:
curl -I https://example.com/app.js
八、总结口诀
静态资源 → 强缓存 + 文件名 hash
HTML → 协商缓存
API → 按需策略(no-cache / private)
公共数据 → CDN + public 缓存
要不要我帮你画一张 HTTP 缓存决策流程图(强缓存 → 协商缓存 → 新请求),这样你在面试或工作解释时更直观?