缓存

前端要控制请求接口的次数时候使用,当某个接口短时间内不断读取,但是数据却不需要一直变化,频繁请求接口会使性能下降,应该采取一些缓存策略

强制缓存

http1.0 强制缓存

通过请求头的expires实现,
看一个例子![[{0178FA88-3861-452D-B53D-C26F03351AB6}.png]]
访问/img/01.jpg 时候,在请求后返回了头expires的时间,expires是一个时间戳,当当前时间戳大于expires,就重新请求接口并写expires,否则直接使用缓存的数据返回,
这样有一个问题,这个时间是根据客户端的手机时间进行判断,但是客户端和服务端的时间可能出现不一致,例如手机设定或者客户端自己修改时间等,这样太过依赖时间戳,于是映入了cache-control

http1.1 cache-control

【强制缓存】cache-control
http1.0用的是expires,http1.1引入了cache-control对于expires进行完善,cache可以设置更多的参数,如上图
访问/img/02.jpg,会写cacge-control,5秒之后过期,这样使用的是服务端的时间戳?不清楚,以后可以自己在serve实现一个这样的缓存

  • cache-control的其他参数
    no-cache和no-store
    no-cache不是字面意思上的不使用缓存,其表示进行强制协商缓存,每次发起请求时候直接与服务端验证,响应会被缓存,但使用需要请求验证
    • public:公共缓存。任何从源服务器到客户端中的每个节点都可以对资源进行缓存。
    • private:私有缓存。仅客户端可以对资源进行缓存。
    • max-age:客户端缓存存储的最长时间,单位秒。判断的优先级高于Expires,客户端会判断资源已缓存的时长是否小于设置的max-age时长。是则直接使用缓存数据,否则会进行Expires的判断流程。

no-store是直接禁用缓存
![[{1623AC34-F442-4CDC-A639-CEF953E64DA7}.png]]

协商缓存

对于http1.0 —-Last Modified

浏览器请求头会带上If-Modified-Since
服务器返回:

  1. 304 Not Modified -> 使用本地缓存
  2. 200 OK -> 使用新内容
    客户端第一次向服务器请求资源时,服务器会返回资源。同时会在响应头中添加Last-Modified字段来表明资源的最后修改时间。当客户端强制缓存失效后,会重新向服务器进行缓存有效性验证。在验证的请求头中,会添加If-Modified-Since字段。服务器会对请求头中的If-Modified-Since和其存储的资源Last-Modified进行比较。若If-Modified-Since的时间不小于Last-Modified,则资源有效,返回304(Not Modified)。否则返回资源本身,并且重新记录文件的Last-Modified

Last-Modified:响应头携带的资源最后修改时间。格式为last-modified:GMT

![[Pasted image 20260213091232.png]]
缺点:
首先,Last-Modified只关注文件的最后修改时间,和文件内容无关。所以文件内容在修改后又重新恢复,也会导致文件的最后修改时间改变。此时客户端的请求则无法使用缓存。

其次,Last-Modified只能监听到秒级别的文件修改,如果文件在1秒内进行了多次修改,那么响应头返回的Last-Modified的时间是不变的。 此时客户端因接收到响应304,会导致资源无法及时更新,使用缓存的资源文件。

http1.1 ETag

基于 ETag 的协商缓存
为了弥补通过时间戳判断的不足,从 HTTP 1.1 规范开始新增了一个 ETag 的头信息,即实体标签(Entity Tag)。

其内容主要是服务器为不同资源进行哈希运算所生成的一个字符串,该字符串类似文件指纹,只要文件内容编码存在差异,对应的 ETag 标签值就会不同,因此可以使用 ETag 对文件资源进行更精准的变化感知。下面我们来看一个使用 ETag 进行协商缓存图片资源的示例,首次请求后的部分响应头关键信息如下:

1
2
3
4
5
/* 响应头 */
Content-Type: image/jpeg
ETag: "c39046a19cd8354384c2de0c32ce7ca3"
Last-Modified: Thu, 29 Apr 2024 03:58:58 GMT
Content-Length: 9887

上述响应头中同时包含了 last-modified 和 ETag 两种协商缓存的有效性校验字段,因为 ETag 比 last-modified 具有更准确的文件资源变化感知,所以它的优先级也更高,二者同时存在时以 ETag 为准。再次对该图片资源发起请求时,会将之前响应头中的 ETag 的字段值作为此次请求头中 If-None-Match 字段,提供给服务器进行缓存有效性验证。请求头与响应头的关键字段信息如下:

1
2
3
4
5
6
7
8
9
/* 再次请求头 */
If-Modified-Since: Thu, 29 Apr 2024 03:58:58 GMT
If-None-Match: "c39046a19cd8354384c2de0c32ce7ca3"

/* 再次响应头 */
Content-Type: image/jpeg
ETag: "c39046a19cd8354384c2de0c32ce7ca3"
Last-Modified: Thu, 29 Apr 2024 03:58:58 GMT
Content-Length: 0

若验证缓存有效,则返回 304 状态码响应重定向到本地缓存,所以上面响应头中的内容长度 Content-Length 字段值也就为 0 了。

强制刷新f5和ctrl+f5对于缓存使用有什么区别

F5(普通刷新)与Ctrl+F5(强制刷新)在缓存使用上的主要区别在于==是否向服务器确认文件更新==。F5 通常使用本地缓存或发起验证(协商缓存),速度较快;Ctrl+F5 强制绕过本地缓存,从服务器重新下载所有资源,确保获取最新数据。

  • F5(普通刷新)
    • 缓存策略:浏览器会检查本地缓存资源。它通常会向服务器发送 If-Modified-SinceIf-None-Match 请求头进行协商。
    • 结果:如果资源未更新,服务器返回 304(Not Modified),浏览器直接使用本地缓存。
    • 适用场景:日常浏览,快速加载页面。
  • Ctrl+F5(强制刷新)
    • 缓存策略:完全无视本地缓存,清除与当前页面相关的临时缓存文件。
    • 结果:浏览器重新向源站发送所有请求(不带缓存校验头),服务器返回 200 OK 并下载全部资源。
    • 适用场景:网站更新后,页面显示样式不正确或数据未更新时(清除缓存,获取最新样式、脚本和图片)。