浏览器缓存
浏览器缓存分为两种:强缓存和协商缓存
大致流程如下面流程图:

强缓存
强缓存是强制让浏览器查看本地缓存(带先后顺序)
- 内存缓存,from memory cache
- 磁盘缓存,from disk cache
没过期且命中就不发http请求,用缓存的资源就行
过期时间由上一次请求,服务器响应头里的cache-control或expire字段去控制
Cache-Control(HTTP/1.1,推荐)
常用的指令有这些:
| 指令 | 用法 |
|---|---|
| max-age=秒 | 缓存有效期(相对时间)。比如 max-age=3600 表示未来 1 小时内直接走缓存 |
| public | 允许客户端和代理服务器(如 CDN)缓存 |
| private | 只允许客户端缓存,不允许 CDN 缓存 |
| no-cache | 不走强缓存,每次都得去服务器验证(走协商缓存) |
| no-store | 完全不缓存,每次都重新下载完整资源 |
Expires(HTTP/1.0,遗留)
指定一个绝对过期时间,比如 Expires: Wed, 21 Oct 2026 07:28:00 GMT。
如果 Cache-Control 和 Expires 同时存在,Cache-Control 优先级更高。现在基本都用 Cache-Control(expire极其依赖本地时间,如果本地时间不准就完蛋了)
协商缓存
强缓存过期了,或者响应头设置了 Cache-Control: no-cache,浏览器就会走协商缓存。
协商缓存必须发请求去问服务器。浏览器会带上上一次请求时服务器给的两个“凭证”之一:
- ETag:资源文件的唯一标识(指纹),由服务器生成
- Last-Modified:资源文件在服务器上的最后修改时间
下次请求时,浏览器把这两个值分别放到请求头里带过去:
- If-None-Match → ETag
- If-Modified-Since → Last-Modified
服务器收到后开始验证:
如果资源没变 → 返回 304 Not Modified,告诉浏览器用本地的缓存
如果资源变了 → 返回 200 OK 和新资源文件,同时更新响应头里的 ETag 和 Last-Modified
ETag优先级也是高于Last-Modified的,Last-Modified 只能精确到秒,如果文件在 1 秒内改了多次,它就检测不出来。而 ETag 是基于文件内容的,只要内容变了一点,指纹就变了。
浏览器缓存的必要性
个人理解,强缓存是为了极致的响应速度,不发http请求直接走本地拿资源,提升用户体验速度。协商缓存的首要目的则是减少传输体积。
所以核心就:提升用户体验、减少服务器压力、减小传输体积