文章目录
以下是整理后的关于HTTP缓存的内容,修正了错误并补充了缺失的知识点:
HTTP缓存
HTTP缓存是一种在客户端或代理服务器本地存储资源副本的机制,旨在提高访问效率和减少带宽消耗。当客户端再次请求已经缓存的资源时,会优先检查本地缓存是否有效。如果存在有效缓存,直接使用本地缓存数据,而无需再次通过网络获取服务器的响应。这就是HTTP缓存的基本原理。
HTTP缓存主要有两种实现方式:强制缓存 和协商缓存。
强制缓存
强制缓存是指浏览器判断请求的资源是否命中强缓存规则,如果命中,则直接从本地缓存读取资源,无需与服务器进行任何通讯。
-
Expires(已弃用) :这是HTTP/1.0的缓存机制,服务器通过
Expires
头部指定资源过期时间。浏览器通过比较本地时间与Expires
指定的时间来判断缓存是否有效。然而,由于Expires
依赖客户端的本地时间,如果客户端的时间不准确,可能导致缓存判断出错。正因为如此,Expires
在现代浏览器中已经基本被废弃,取而代之的是Cache-Control
。 -
Cache-Control :这是HTTP/1.1引入的更为精确的缓存控制机制,通过在
Cache-Control
头部指定缓存策略和过期时间,控制资源的缓存行为。Cache-Control
支持多个指令,其中包括:max-age=N
:指定资源从请求时间开始缓存的最大有效时间(秒)。s-maxage=N
:专门针对共享缓存(如CDN),指定资源的缓存时间。no-cache
:不使用强制缓存,每次请求都必须向服务器进行验证(走协商缓存)。no-store
:禁止任何形式的缓存,资源每次都必须从服务器获取。public
:资源可以被浏览器和代理服务器缓存。private
:资源只能被浏览器缓存,不允许代理服务器缓存。
强制缓存的工作流程:
- 浏览器首次请求资源时,服务器在响应中设置
Cache-Control
头部,并指定缓存策略。 - 浏览器在后续请求时,首先检查该资源是否命中强制缓存,如果未过期,则直接使用缓存,否则发起新的请求。
- 如果缓存过期,服务器将重新返回资源并更新
Cache-Control
头部。
协商缓存
当强制缓存失效或Cache-Control
设置为no-cache
时,浏览器会与服务器协商是否可以继续使用本地缓存,这种机制称为协商缓存。
- Last-Modified 和 If-Modified-Since :通过资源的最后修改时间来判断缓存是否有效。
- 服务器在首次响应时,返回资源的最后修改时间,并通过
Last-Modified
头部传递给客户端。 - 客户端在后续请求时,通过
If-Modified-Since
头部携带上次获取的Last-Modified
时间值。 - 服务器比较资源的最后修改时间和
If-Modified-Since
的时间,如果资源未修改,则返回304状态码,表示客户端可以使用本地缓存,否则返回新资源。
- 服务器在首次响应时,返回资源的最后修改时间,并通过
缺点:
-
因为基于修改时间判断,如果文件内容未改动但修改时间变动(如改名等),会导致不必要的缓存失效。
-
Last-Modified
精度为秒,短时间内的多次修改可能导致缓存判断失误。 -
ETag 和 If-None-Match:使用资源的指纹(哈希值)判断缓存是否有效。
- 服务器在响应时为资源生成唯一的
ETag
(实体标签),并通过头部传递给客户端。 - 客户端在后续请求时,通过
If-None-Match
头部携带上次获取的ETag
值。 - 服务器比较当前资源的
ETag
与If-None-Match
的值,如果一致,则返回304状态码,表示缓存有效;否则返回新资源及更新后的ETag
。
- 服务器在响应时为资源生成唯一的
优点:
- ETag更为精确,能捕捉到细微的内容变化,解决了
Last-Modified
可能忽略细微修改的问题。
缺点:
- 计算
ETag
需要一定的服务器资源,对于大型文件或高频访问场景,可能带来性能开销。 ETag
支持强校验和弱校验,强校验基于每个字节的内容生成哈希值,虽然精确但计算量大;弱校验通过部分内容生成哈希值,计算速度快但可能降低准确性。
协商缓存的工作流程:
- 当强制缓存未命中时,浏览器会根据上次响应的
Last-Modified
或ETag
信息发起带有协商缓存字段的请求。 - 服务器根据客户端的
If-Modified-Since
或If-None-Match
进行缓存验证,并决定是否返回304状态码(缓存有效)或新的资源。
总结
HTTP缓存通过强制缓存和协商缓存两种方式,显著提高了资源访问的效率,减少了不必要的网络传输。在实际开发中,合理配置Cache-Control
、ETag
等缓存机制,可以极大提升用户体验和服务器性能。