1. 强缓存(Strong Cache)
定义
强缓存是指在缓存的资源有效期内,浏览器会直接使用缓存中的数据,而不会发起网络请求。也就是说,浏览器会直接从本地缓存读取资源,不会与服务器进行任何交互。
如何控制强缓存
强缓存的实现依赖于 HTTP 头部的 Cache-Control
和 Expires
。
Cache-Control
: 控制缓存的策略,主要用于现代浏览器,提供更细粒度的控制。Expires
: 指定资源的过期时间。这个头部是 HTTP/1.0 中引入的,过期时间以 GMT 格式表示。
主要指令
- Cache-Control: max-age=
- 该指令表示缓存资源的有效期,单位为秒。
- 示例:
Cache-Control: max-age=3600
表示资源在 3600 秒内有效,即 1 小时内浏览器不会请求服务器。
- Expires:
- 表示资源的过期时间,单位为日期。
- 示例:
Expires: Wed, 21 Oct 2023 07:28:00 GMT
表示缓存资源有效期直到 2023 年 10 月 21 日 07:28:00 GMT。 Expires
头是基于客户端的时间,若浏览器的本地时间不准确可能会导致缓存的意外失效。
强缓存工作流程
- 当浏览器请求资源时,会首先检查缓存中是否存在符合
Cache-Control
或Expires
的缓存。 - 如果缓存有效,浏览器会直接使用缓存,而不会向服务器发起请求。
例子
Cache-Control: max-age=86400
表示该资源在 86400 秒(即 1 天)内有效,过期后需要重新请求。
2. 协商缓存(Conditional Cache)
定义
协商缓存是指浏览器向服务器发送请求时,即使缓存中有资源,仍然会附带一些条件,询问服务器该资源是否更新。如果服务器认为缓存有效,则返回 304 Not Modified
状态码,不需要重新发送资源。如果缓存过期或有更新,服务器会返回新的资源。
如何控制协商缓存
协商缓存的实现依赖于 Last-Modified
和 If-Modified-Since
,以及 ETag
和 If-None-Match
。
- Last-Modified 和 If-Modified-Since
Last-Modified
: 服务器返回资源最后一次修改的时间。If-Modified-Since
: 浏览器在请求时携带的请求头,告诉服务器资源上次修改的时间,服务器会检查该时间与当前时间是否一致。- 如果自上次修改后没有变化,服务器返回
304 Not Modified
,客户端继续使用缓存。
- ETag 和 If-None-Match
ETag
: 是服务器返回的资源唯一标识符(一般为哈希值),可以判断资源是否变化。If-None-Match
: 浏览器发送请求时附带的头,携带当前缓存的ETag
值,服务器根据该值判断资源是否变化。- 如果资源未变更,服务器返回
304 Not Modified
,否则返回最新资源。
其实 Etag 和 Last-Modified 一样的,只不过 Etag 是服务端对资源按照一定方式(比如 contenthash)计算出来的唯一标识,就像人类指纹一样,传给客户端之后,客户端再传过来时候,服务端会将其与现在的资源计算出来的唯一标识做比较,一致则返回 304,不一致就返回 200 和新的资源及新的 Etag。
两者比较:
- 优先使用 Etag。
- Last-Modified 只能精确到秒级。
- 如果资源被重复生成,而内容不变,则 Etag 更精确。
协商缓存工作流程
- 浏览器首先检查是否有缓存,如果有缓存,浏览器会发送请求并携带
If-Modified-Since
或If-None-Match
请求头。 - 服务器根据这些信息判断资源是否更新,如果未更新,则返回
304 Not Modified
,并让浏览器继续使用本地缓存。 - 如果资源已更新,则返回最新的资源。
例子
-
服务器返回资源时:
Last-Modified: Mon, 18 Jan 2023 10:00:00 GMT
-
浏览器发起请求时:
If-Modified-Since: Mon, 18 Jan 2023 10:00:00 GMT
-
如果资源未修改,服务器返回:
HTTP/1.1 304 Not Modified
3. 强缓存与协商缓存的关系
- 强缓存:在缓存有效期内,浏览器不会与服务器交互,直接从缓存读取数据。主要依赖
Cache-Control
和Expires
头部。 - 协商缓存:即使有缓存,浏览器也会向服务器发送请求,询问缓存是否有效,服务器根据条件判断是否更新缓存。主要依赖
Last-Modified
、ETag
以及If-Modified-Since
和If-None-Match
。
4. 强缓存和协商缓存的区别
- 强缓存:直接使用本地缓存,不会向服务器发送请求,速度最快。
- 协商缓存:浏览器会向服务器询问缓存是否有效,只有在资源变化时才会从服务器获取新的资源。
5. 总结
- 强缓存 是由浏览器通过 HTTP 头部中的
Cache-Control
或Expires
控制的,当缓存有效时,浏览器直接从缓存读取。 - 协商缓存 依赖于
Last-Modified
和ETag
,它通过向服务器发送条件请求,确保缓存资源是否更新。优先使用 Etag。 - 强缓存 和 协商缓存 组合使用,可以有效提高性能并减少不必要的网络请求。
三种刷新操作对 http 缓存的影响:
- 正常操作:地址栏输入 url,跳转链接,前进后退等。强制缓存有效,协商缓存有效。
- 手动刷新:f5,点击刷新按钮,右键菜单刷新。强制缓存失效,协商缓存有效。
- 强制刷新:ctrl + f5,shift+command+r。强制缓存失效,协商缓存失效。