HTTP缓存的前世今生

116 阅读3分钟
    /**
        @date 2023-02-09
        @description HTTP缓存的前世今生
        */

壹(序)

HTTP 缓存不仅是客户端的优化,还是为了减轻服务器端的压力,随着 HTTP 的不断发展,缓存方案也越来越多,越来越完善,这次就聊一聊 HTTP 缓存的前世今生。

缓存又分为强缓存和协商缓存;

强缓存指的是客户端不需要发送请求到服务器端,只要不过期就直接使用缓存中的资源,状态码为 200,不过会标识当前 from xxx,如图:

强缓存.jpg

协商缓存就是有一个协商的过程,因为服务器端资源可能在未过期时发生变化,这种时候就需要判断是否需要返回新的资源,协商缓存会发送请求,如果可以直接使用缓存的资源,状态码则返回 304,资源更新需要重新拉取资源则返回 200,正常返回资源,如图:

协商缓存.jpg

贰(Expires-强缓存)

在 HTTP 缓存只具备缓存功能时,存在的问题是服务器端资源更新时客户端无法拿到最新的资源,所以增加了一个过期时间,服务器端与客户端时间对不上时则重新从服务器拉取资源,应运而生的就是 Expires;

示例:

Expires: Wed, 21 Oct 2015 07:28:00 GMT

表示在该时间之后过期,同时 0 表示已经过期

图示:

expires.jpg

叁(Cache-Control-强缓存)

既然已经有了 Expires,为什么还需要 Cache-Control 呢?

原因在于 Expires 可能出现时间难以解析,或者客户端与服务器端日期不一致导致拿不到正常的资源过期情况,所以一种新的缓存方式产生了,就是 Cache-Control;

Cache-Control 不再使用具体的日期,而是标明资源的最大过期时间,这样就避免了 Expires 两个端日期无法比较的问题;

常用指令:

max-age: number // 缓存的最长周期,单位为 s,超过该事件表示过期
no-chche // 并不是不缓存,而是可以缓存,但是每次使用之前必须给原始服务器验证,即是不使用强缓存
no-store // 明确表示不能使用缓存 
private // 只允许在客户端本地(如浏览器)缓存
public // 允许客户端、服务器端、代理服务器缓存

图示:

cache-control.jpg

肆(Last-Modified-协商缓存)

Last-Modified/If-Modified-Since 是协商缓存的解决方案,Last-Modified 会标注资源的最后修改时间,返回给客户端后客户端带上 If-Modified-Since,其值就是服务器端返回的 Last-Modified,每次请求资源时通过比较两者来判断是否需要返回新的资源;

示例:

Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT
If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT

图示: last-modified.jpg

伍(ETag-协商缓存)

由于 Last-Modified 是秒级别的,所以不够精确,如果在某一秒内资源发生改变,但是判断已经通过然后返回了 304,就会出现资源不一致的问题,所以使用了新的 ETag 来进行协商缓存;

ETag 是生成一个资源唯一标识,客户端接收到 ETag 后,发送请求时带上 If-None-Match,服务器端再进行比较,不一致则表示资源变化,需要返回新的资源;

示例:

ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

图示:

ETag.jpg