在 Web 开发中,缓存机制是提高页面加载速度和用户体验的重要技术。缓存分为两种主要类型:强缓存和协商缓存。本文将详细介绍这两种缓存机制的原理、实现方式及其区别,并演示如何在 <meta>
元素中和 Nginx 服务器中进行缓存控制。
强缓存
强缓存(Strong Caching)是指在缓存期间,客户端不需要向服务器发送请求,直接从本地缓存中读取资源。这可以显著减少网络请求,提升页面加载速度。
实现方式
强缓存通过响应头中的 Expires
或 Cache-Control
实现:
- Expires
Expires
头指定资源的过期时间,是一个绝对时间点。超过这个时间点,缓存就会失效,浏览器必须再次请求资源。
- 示例:
Expires: Wed, 21 Oct 2021 07:28:00 GMT
- 解析:
在 Expires
指定的时间之前,浏览器会直接从缓存中读取资源,不会向服务器发送请求。
- Cache-Control
Cache-Control
头使用相对时间来指定资源的缓存时间,提供了更为灵活的缓存控制。常用的指令包括:
-
max-age
:指定资源缓存的最大有效时间,单位为秒。 -
public
:表示响应可以被任何缓存区缓存(如浏览器、CDN 等)。 -
private
:表示响应只能被单个用户缓存(即浏览器),不能被共享缓存区缓存。 -
no-cache
:缓存资源,但每次请求必须向服务器进行验证。 -
no-store
:不缓存资源,每次请求都从服务器获取。 -
示例:
Cache-Control: max-age=3600
- 解析:
max-age=3600
指定资源可以缓存 3600 秒(1 小时)。在此期间,浏览器直接从缓存中读取资源。
协商缓存
协商缓存(Conditional Caching)是指在缓存过期后,客户端每次请求资源时都会向服务器验证缓存资源的有效性。只有在资源更新时才会下载新的资源,否则继续使用缓存。
实现方式
协商缓存通过 Last-Modified
/If-Modified-Since
和 ETag
/If-None-Match
头实现:
- Last-Modified / If-Modified-Since
- Last-Modified:服务器响应头,表示资源的最后修改时间。
Last-Modified: Wed, 21 Oct 2021 07:28:00 GMT
- If-Modified-Since:客户端请求头,表示上次缓存的资源的最后修改时间。
If-Modified-Since: Wed, 21 Oct 2021 07:28:00 GMT
-
工作原理:
- 客户端缓存资源时,记录资源的
Last-Modified
时间。 - 下次请求该资源时,客户端在请求头中包含
If-Modified-Since
。 - 服务器根据资源的最后修改时间和
If-Modified-Since
的值进行比较:- 如果资源未修改,返回
304 Not Modified
,客户端继续使用缓存。 - 如果资源已修改,返回新的资源和
200 OK
,客户端更新缓存。
- 如果资源未修改,返回
- 客户端缓存资源时,记录资源的
- ETag / If-None-Match
- ETag:服务器响应头,表示资源的唯一标识符(如哈希值)。
ETag: "5d8c72a5edda3"
- If-None-Match:客户端请求头,包含上次缓存的资源的 ETag。
If-None-Match: "5d8c72a5edda3"
-
工作原理:
- 客户端缓存资源时,记录资源的 ETag。
- 下次请求该资源时,客户端在请求头中包含
If-None-Match
。 - 服务器根据资源的 ETag 和
If-None-Match
的值进行比较:- 如果 ETag 未变化,返回
304 Not Modified
,客户端继续使用缓存。 - 如果 ETag 已变化,返回新的资源和
200 OK
,客户端更新缓存。
- 如果 ETag 未变化,返回
强缓存与协商缓存的区别
-
强缓存:
- 在缓存有效期内,客户端不向服务器发送请求。
- 通过
Exp