一、强缓存(强制缓存)
(一)引入的HTTP版本
- HTTP/1.0:引入了
Expires头字段。 - HTTP/1.1:引入了
Cache-Control头字段,取代了Expires。
(二)特点
-
Expires(HTTP/1.0)-
定义:
Expires是一个绝对时间,用于指定资源的过期时间。 -
特点:
- 客户端在请求资源时,会检查本地缓存的
Expires时间。如果当前时间早于Expires时间,客户端会直接使用本地缓存,而不会向服务器发送请求。 - 优点是简单直接,但缺点是依赖于客户端和服务器的系统时间同步。如果客户端时间不准确,可能会导致缓存失效或缓存被误用。
- 客户端在请求资源时,会检查本地缓存的
-
示例:
HTTP/1.0 200 OK Expires: Wed, 21 Oct 2025 07:28:00 GMT
-
-
Cache-Control(HTTP/1.1)-
定义:
Cache-Control是一个指令集,用于更灵活地控制缓存行为。其中,max-age是最重要的指令,表示资源的相对过期时间(以秒为单位)。 -
特点:
max-age使用相对时间,避免了因客户端和服务器时间不一致导致的问题。- 提供了更丰富的指令,如
private(仅在客户端缓存)、public(可在任何地方缓存)、no-cache(不使用缓存,但可以存储缓存)、no-store(不存储任何缓存)等。 - 优先级高于
Expires,如果同时存在,Cache-Control会覆盖Expires。
-
示例:
HTTP/1.1 200 OK Cache-Control: max-age=3600
-
(三)服务器更新处理
-
问题:如果服务器上的资源已经更新,但客户端仍然使用本地缓存(因为缓存未过期),会导致客户端看到的不是最新内容。
-
处理方式:
- 修改资源的URL:这是最常用的方式。例如,将资源的URL从
style.css改为style-v2.css,或者在URL中添加版本号或时间戳(如style.css?v=20250416)。这样,客户端会请求新的URL,从而获取到更新后的资源。 - 缩短缓存时间:将
max-age设置为较短的时间(如几分钟),这样可以减少客户端使用过时缓存的可能性,但会增加服务器的请求量。
- 修改资源的URL:这是最常用的方式。例如,将资源的URL从
二、协商缓存(验证缓存)
(一)引入的HTTP版本
- HTTP/1.0:引入了
Last-Modified和If-Modified-Since。 - HTTP/1.1:引入了
ETag和If-None-Match。
(二)特点
-
Last-Modified和If-Modified-Since(HTTP/1.0)-
定义:
Last-Modified:服务器在响应中返回资源的最后修改时间。If-Modified-Since:客户端在请求时,将上次获取的Last-Modified时间发送给服务器,服务器根据该时间判断资源是否发生变化。
-
特点:
- 如果资源自上次请求后未发生变化,服务器返回
304 Not Modified,客户端直接使用本地缓存。 - 优点是简单,但缺点是只能精确到秒,对于频繁更新的资源(如每秒更新多次)不够精确。
- 如果资源自上次请求后未发生变化,服务器返回
-
示例:
HTTP/1.0 200 OK Last-Modified: Wed, 21 Oct 2025 07:28:00 GMT
-
-
ETag和If-None-Match(HTTP/1.1)-
定义:
ETag:服务器在响应中返回资源的唯一标识符(通常是文件的哈希值或版本号)。If-None-Match:客户端在请求时,将上次获取的ETag值发送给服务器,服务器通过比较ETag值来判断资源是否发生变化。
-
特点:
ETag的精度更高,可以精确到资源的每一个字节,适合频繁更新的资源。- 与
Last-Modified相比,ETag可以更好地处理资源的微小变化。
-
示例:
HTTP/1.1 200 OK ETag: "123456789abcdef"
-
(三)服务器更新处理
-
问题:服务器上的资源更新后,客户端需要能够及时获取到更新后的资源。
-
处理方式:
-
Last-Modified方式:- 当资源更新时,服务器更新
Last-Modified时间。客户端在请求时通过If-Modified-Since发送上次获取的时间,服务器比较后如果发现资源已更新,则返回新的资源和新的Last-Modified时间。
- 当资源更新时,服务器更新
-
ETag方式:- 当资源更新时,服务器生成新的
ETag值。客户端在请求时通过If-None-Match发送上次获取的ETag值,服务器比较后如果发现ETag不匹配,则返回新的资源和新的ETag值。
- 当资源更新时,服务器生成新的
-
示例:
-
客户端请求:
GET /resource HTTP/1.1 If-None-Match: "123456789abcdef" -
服务器响应(如果资源未变化):
HTTP/1.1 304 Not Modified -
服务器响应(如果资源已变化):
HTTP/1.1 200 OK ETag: "987654321fedcba" Content-Type: text/html <new resource content>
-
-