概述
浏览器的缓存机制通过将请求过的web资源(如HTML页面、图片、JavaScript文件等)的副本保存在本地,以便在后续请求相同资源时能够直接使用缓存中的副本,而不是每次都从服务器重新下载。这样做可以显著提高网页的加载速度,减轻服务器的负担,并减少网络带宽的消耗。
原理
缓存过程
-
请求与响应:浏览器首先向服务器发送HTTP请求,服务器在响应请求时,会在HTTP响应报文中包含一些与缓存相关的字段(如Cache-Control、Expires、Last-Modified、Etag等)。
-
缓存决策:浏览器根据响应报文中的缓存字段,决定是否将资源副本存入缓存,并设置相应的缓存规则(如缓存有效期、验证机制等)。
-
后续请求处理:当浏览器再次请求相同资源时,会先检查本地缓存中是否有该资源的副本以及缓存是否有效。如果缓存有效,则直接使用缓存中的副本;如果缓存无效或不存在,则向服务器发送新的请求。
缓存类型
浏览器缓存机制主要分为两类:强制缓存和协商缓存。
-
强制缓存:
- 概述:强制缓存是指浏览器在本地缓存中查找请求的资源,并根据缓存规则(如Expires和Cache-Control字段)决定是否直接使用缓存副本的过程。
- 字段:
- Expires:HTTP/1.0中用于控制网页缓存的字段,表示资源缓存的到期时间。如果客户端的时间小于Expires的值,则直接使用缓存结果。但在HTTP/1.1中,Expires字段已被Cache-Control替代。
- Cache-Control:HTTP/1.1中最重要的缓存控制字段,用于控制网页缓存的多个方面。常用的值包括
public
(所有内容都将被缓存)、no-store
(所有内容都不会被缓存)、max-age=xxx
(缓存内容将在xxx秒后失效)等。
-
协商缓存:
- 概述:协商缓存是在强制缓存失效后,浏览器携带缓存标识(如Last-Modified和Etag字段)向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程。
- 字段:
- Last-Modified / If-Modified-Since:Last-Modified是服务器响应请求时返回的资源文件在服务器最后被修改的时间。If-Modified-Since是客户端再次发起请求时携带的字段,其值为上次请求时服务器返回的Last-Modified值。服务器通过比较这两个时间值来决定是否返回304状态码(资源未修改,使用缓存)或200状态码(资源已修改,返回新资源)。
- Etag / If-None-Match:Etag是服务器响应请求时返回的资源文件的唯一标识。If-None-Match是客户端再次发起请求时携带的字段,其值为上次请求时服务器返回的Etag值。服务器通过比较这两个值来决定是否返回304状态码或200状态码。
HTTP缓存控制字段
HTTP缓存控制字段是HTTP协议中用于控制资源缓存行为的关键组成部分。这些字段告诉浏览器、缓存服务器或代理服务器如何存储、验证和使用缓存的资源。以下是几个重要的HTTP缓存控制字段的详细解释:
1. Cache-Control
Cache-Control字段是HTTP/1.1中引入的,用于定义缓存的策略和指令。它既可以出现在请求头中,也可以出现在响应头中。Cache-Control字段的重要性在于它能够覆盖其他缓存相关的设置,如Expires和Last-Modified,提供更可靠的缓存控制机制。
常用指令包括:
- public:表示响应可以被任何缓存所缓存。
- private:表示响应只能被单个用户(如浏览器)缓存,不能被共享缓存(如CDN)缓存。
- no-cache:表示缓存资源前必须验证其有效性,即使资源存在缓存中,也需要向服务器发送请求以确认资源是否已被修改。
- no-store:表示资源不应该被缓存。
- max-age=xxx:定义缓存资源的最大有效时间(秒)。在有效期内,资源可以直接从缓存中提供,无需再次验证。
- must-revalidate:指示缓存资源在过期后必须向服务器进行验证,但在验证过程中,如果服务器无法联系上,则可以返回过期的缓存资源。
2. Expires
Expires字段是HTTP/1.0中定义的,用于指定资源的过期时间。如果客户端的时间小于Expires的时间,那么就可以直接使用缓存中的资源,而无需向服务器发送请求。然而,在HTTP/1.1中,Expires字段的使用已经被Cache-Control的max-age指令所取代,因为max-age提供了更灵活和精确的缓存控制。
格式:Expires: Sat, 25 Feb 2012 12:22:17 GMT
,后面跟着一个GMT格式的日期和时间。
3. Last-Modified 和 If-Modified-Since
Last-Modified字段是服务器在响应中发送的,表示资源最后修改的时间。客户端(如浏览器)在下次请求时,可以发送If-Modified-Since字段,该字段的值是之前服务器响应中Last-Modified字段的值。如果资源自上次请求以来没有修改过,服务器将返回304 Not Modified响应,表示客户端可以继续使用缓存中的资源。
工作流程:
- 服务器首次响应请求时,包含Last-Modified字段。
- 客户端再次请求时,在请求头中包含If-Modified-Since字段。
- 服务器检查If-Modified-Since字段与资源最后修改时间,如果相同,则返回304响应;如果不同,则返回完整的资源内容。
4. ETag 和 If-None-Match
ETag是服务器为每个资源生成的一个唯一标识符。客户端在下次请求时,可以在请求头中包含If-None-Match字段,其值是之前服务器响应中ETag字段的值。如果资源的ETag自上次请求以来没有变化,服务器将返回304 Not Modified响应,表示客户端可以继续使用缓存中的资源。
工作流程:
- 服务器首次响应请求时,包含ETag字段。
- 客户端再次请求时,在请求头中包含If-None-Match字段。
- 服务器检查If-None-Match字段与资源当前的ETag值,如果相同,则返回304响应;如果不同,则返回完整的资源内容。
总结
HTTP缓存控制字段通过精确控制资源的缓存行为,有助于提升网页的加载速度、减少网络带宽的消耗和降低服务器的负载。在实际应用中,这些字段可以单独使用,也可以组合使用,以实现复杂的缓存策略。