缓存工作流程
当浏览器请求某个资源时,缓存机制的基本流程如下:
- 检查缓存:浏览器检查其缓存中是否有可用的副本。
- 使用缓存:如果缓存有效,直接使用该副本;如果无效或不存在,则向服务器发起请求。
- 服务器响应:服务器可以返回资源并附上将来可以必须/使用缓存的相关信息(例如,
Cache-Control
头)。 - 更新缓存:浏览器将新的资源存入缓存,以备将来使用。
Cache-Control
和 Expires
都是用于控制 HTTP 缓存行为的头部字段,但它们在使用方式和功能上有一些不同。以下是这两个字段的详细对比和说明:
Cache-Control
-
定义:
Cache-Control
是用于 HTTP/1.1 协议的缓存控制头部,用于精确控制代理服务器和浏览器的缓存策略。 -
语法:可以包含多个指令,常见的指令包括:
public
:响应可以被所有缓存存储。private
:响应只能被用户的浏览器缓存,其他共享缓存(如代理服务器)不能缓存。no-cache
:在使用缓存之前,必须向服务器验证资源。no-store
:请求和响应都不应该被缓存。max-age
:指定资源在缓存中有效的秒数。例如,max-age=3600
表示该资源在缓存中可以存储 1 小时。must-revalidate
:表示一旦资源过期,必须向服务器重新验证后才能使用缓存。
-
使用场景:适合需要更灵活和更具体缓存控制的情况,能够在请求和响应中动态地设定缓存行为。
Expires
-
定义:
Expires
是 HTTP/1.0 中引入的缓存控制头部,用于指定资源的过期时间。它的值为一个具体的日期和时间。 -
语法:格式为:
yaml Expires: Wed, 21 Oct 2025 07:28:00 GMT
-
功能:表示响应的有效期限,超过此时间后,缓存的资源被视为过期。
-
使用局限:由于
Expires
是基于绝对时间的,与当前时间的对比不够灵活,而且它的效果依赖于客户端和服务器的时间同步,因此在现代应用中通常不太推荐使用。
对比总结
表格
特性 | Cache-Control | Expires |
---|---|---|
规范 | HTTP/1.1 | HTTP/1.0 |
定义方式 | 可使用多种指令,灵活控制 | 使用具体的过期日期和时间 |
适用性 | 更为现代和灵活,推荐使用 | 只在过期后失效,易于出错 |
示例 | Cache-Control: max-age=3600 | Expires: Wed, 21 Oct 2025 07:28:00 GMT |
建议
- 在现代 Web 开发中,通常推荐使用
Cache-Control
头部,因为它提供了更细粒度的控制和灵活性。 - 如果同时使用
Cache-Control
和Expires
,Cache-Control
的优先级通常更高。
如何判断缓存过期
HTTP缓存判断资源是否过期的机制主要依赖于HTTP头部字段中的信息。判断一个缓存资源是否过期的方式可以分为以下几种情况:
1. 使用 Cache-Control
和 max-age
-
max-age:这是最常用的方式。它指定了从响应被发送到缓存开始计算的最大有效时间(以秒计)。比如,
Cache-Control: max-age=3600
表示该资源在缓存中有效时间为 1 小时(3600秒)。判断逻辑:
- 缓存中存储该资源的时间 +
max-age
> 当前时间 → 资源仍然有效。 - 否则,资源过期。
- 缓存中存储该资源的时间 +
2. 使用 Expires
-
Expires:这是 HTTP/1.0 中的一个字段,指向一个具体的日期和时间,表示资源过期的绝对时间。格式为,例如:
Expires: Wed, 21 Oct 2025 07:28:00 GMT
。判断逻辑:
- 当前时间 <
Expires
时间 → 资源有效。 - 否则,资源过期。
- 当前时间 <
3. 使用 Last-Modified
和 If-Modified-Since
-
Last-Modified:响应被缓存时的最后修改日期。
-
If-Modified-Since:客户端在向服务器请求资源时发送该头部,告诉服务器希望获取的是在某个时间之后修改过的资源。
判断逻辑:
- 客户端每次请求时,带上
If-Modified-Since
头部,便于服务器判断自上次请求后资源是否被修改。 - 如果资源在
Last-Modified
之后没有变化,服务器可以返回 304 Not Modified 响应,表示可以继续使用缓存的副本。
- 客户端每次请求时,带上
4. 使用 ETag
和 If-None-Match
-
ETag:表示资源内容的特定版本。当资源被修改时,ETag的值也会改变。
-
If-None-Match:在发起请求时,客户端会把上一次接收到的 ETag 值放在这个头部里。
判断逻辑:
- 服务器检查客户端发来的 ETag 是否与当前资源的 ETag 相匹配。
- 如果匹配,资源未修改,返回 304 Not Modified;如果不匹配,返回最新的资源及其新的 ETag。
小结
HTTP缓存的过期判断由多个头部字段共同决定,使用上通常会结合相应的策略,例如:
- 使用
Cache-Control
和Expires
来设定过期时间,或者 - 利用
Last-Modified
和ETag
机制来通过条件请求优化缓存行为。