/**
@date 2023-02-09
@description HTTP缓存的前世今生
*/
壹(序)
HTTP 缓存不仅是客户端的优化,还是为了减轻服务器端的压力,随着 HTTP 的不断发展,缓存方案也越来越多,越来越完善,这次就聊一聊 HTTP 缓存的前世今生。
缓存又分为强缓存和协商缓存;
强缓存指的是客户端不需要发送请求到服务器端,只要不过期就直接使用缓存中的资源,状态码为 200,不过会标识当前 from xxx,如图:
协商缓存就是有一个协商的过程,因为服务器端资源可能在未过期时发生变化,这种时候就需要判断是否需要返回新的资源,协商缓存会发送请求,如果可以直接使用缓存的资源,状态码则返回 304,资源更新需要重新拉取资源则返回 200,正常返回资源,如图:
贰(Expires-强缓存)
在 HTTP 缓存只具备缓存功能时,存在的问题是服务器端资源更新时客户端无法拿到最新的资源,所以增加了一个过期时间,服务器端与客户端时间对不上时则重新从服务器拉取资源,应运而生的就是 Expires;
示例:
Expires: Wed, 21 Oct 2015 07:28:00 GMT
表示在该时间之后过期,同时 0 表示已经过期
图示:
叁(Cache-Control-强缓存)
既然已经有了 Expires,为什么还需要 Cache-Control 呢?
原因在于 Expires 可能出现时间难以解析,或者客户端与服务器端日期不一致导致拿不到正常的资源过期情况,所以一种新的缓存方式产生了,就是 Cache-Control;
Cache-Control 不再使用具体的日期,而是标明资源的最大过期时间,这样就避免了 Expires 两个端日期无法比较的问题;
常用指令:
max-age: number // 缓存的最长周期,单位为 s,超过该事件表示过期
no-chche // 并不是不缓存,而是可以缓存,但是每次使用之前必须给原始服务器验证,即是不使用强缓存
no-store // 明确表示不能使用缓存
private // 只允许在客户端本地(如浏览器)缓存
public // 允许客户端、服务器端、代理服务器缓存
图示:
肆(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
图示:
伍(ETag-协商缓存)
由于 Last-Modified 是秒级别的,所以不够精确,如果在某一秒内资源发生改变,但是判断已经通过然后返回了 304,就会出现资源不一致的问题,所以使用了新的 ETag 来进行协商缓存;
ETag 是生成一个资源唯一标识,客户端接收到 ETag 后,发送请求时带上 If-None-Match,服务器端再进行比较,不一致则表示资源变化,需要返回新的资源;
示例:
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"
图示: