侧边栏壁纸
  • 累计撰写 244 篇文章
  • 累计创建 16 个标签
  • 累计收到 0 条评论
隐藏侧边栏

HTTP 缓存的工作原理和实现机制(下)

kaixindeken
2021-04-23 / 0 评论 / 0 点赞 / 69 阅读 / 2,094 字

Cache-Control

在 HTTP/1.0 中通过 Expires 首部字段来判断缓存是否过期,但是 Expires 字段值是一个绝对日期,有其局限性,在 HTTP/1.1 中我们统一通过 Cache-Control 字段来控制缓存的有效期及实现细节。可以说 Cache-Control 是 HTTP 缓存相关首部字段中最重要的一个字段,下面我们具体来看如果通过该字段设置 HTTP 缓存。

在 Cache-Control 字段中可以设置多个属性值,不同属性值之间通过逗号分隔,作为一个通用首部字段,请求头和响应头中都可以出现这个字段,并且通过不同的属性值来定义 HTTP 缓存策略。常见的属性及其含义如下所示:

  • no-store:禁止进行缓存,缓存中不得存储任何关于客户端请求和服务端响应的内容,每次由客户端发起的请求都会从服务端下载完整的响应内容;
  • no-cache:这个属性值很具有迷惑性,它的含义并不是不使用缓存,而是强制确认缓存,每次有请求发出时,缓存会将此请求发到服务器(该请求应该会带有与本地缓存相关的验证字段),服务器端会验证请求中所描述的缓存是否过期,若未过期,则缓存才使用本地缓存副本。该属性和 HTTP/1.0 中的 Pragma: no-cache 等效;
  • public:用于共享缓存,任何中间代理都可以缓存响应;
  • private:用于私有缓存,只有客户端浏览器才可以缓存响应,没有指定 public 时,默认为 private;
  • max-age:用于设置缓存有效期,与 Expires 字段值不同,max-age 是距离请求发起时间的秒数,是一个相对值,从而可以避免客户端与服务端时间不一致导致的误差,如果在响应头中两者都存在,则以 max-age 为准,Expires 自动失效;
  • must-revalidate:使用该指令时,意味着缓存在考虑使用一个陈旧的资源时,必须先验证它的状态,已过期的缓存将不被使用。该属性与 no-cache 的区别在于,使用 no-cache 时,不管本地资源缓存副本是否过期,使用资源缓存副本前,一定要到源服务器进行副本有效性校验,而 must-revalidate 则不然,只有在本地资源缓存副本过期后,才去源服务器进行有效性检测。

关于缓存有效性检测(或者叫做新鲜度检测、服务器再验证),在 HTTP/1.1 协议中可以通过两对首部字段来实现。

Last-Modified/If-Modified-Since

Last-Modified 字段常用于响应头中,告知客户端资源的最后修改时间,这样,当客户端再次请求该资源时,会在 If-Modified-Since 请求头字段中带上上次请求返回的最后修改时间,服务器收到请求报文后发现请求头包含 If-Modified-Since 字段,则与被请求资源的最后修改时间进行对比。如果资源的最后修改时间大于 If-Modified-Since 字段值,说明资源又被改动过,则返回完整的资源内容,对应响应状态码为 200;如果资源的最后修改时间小于或等于 If-Modified-Since 字段值,说明资源没有做新的修改,则返回状态码 304,告知浏览器使用本地保存的缓存作为响应实体。

Etag/If-None-Match

和上面那对首部字段类似,Etag 用于响应头中,告知客户端资源在服务器的唯一标识(生成规则由服务器指定,每当资源发生修改后 Etag 值会变化),当客户端再次请求该资源时,通过 If-None-Match 字段通知服务器客户段缓存资源数据的唯一标识。服务器收到请求报文后发现请求头包含 If-None-Match 字段,则与被请求资源的唯一标识进行对比,如果不同,说明资源又被改动过,则返回完整的资源内容,对应响应状态码为 200;如果相同,说明资源没有做新的修改,则返回状态码 304,告知浏览器使用本地保存的缓存作为响应实体。

需要指出的是 Etag/If-None-Match 的优先级要高于 Last-Modified/If-Modified-Since,如果同时出现,以前者为准。

综上,缓存有效性检测逻辑流程图如下所示:

1.jpeg

如果把范围再扩大到通过 Cache-Control 来定义 HTTP 缓存策略,则对应的流程图如下所示:

1.jpeg

最后一步「Add Etag Header」还可以改为「Add Last-Modified Header」。

以上就是 HTTP 缓存的底层工作原理和实现机制。

0

评论区