网络2️⃣HTTP-缓存

对于一些具有重复性的 HTTP 请求(e.g. 每次请求得到的响应数据相同),

可以将这对请求-响应的数据缓存在本地,下次可直接读取本地数据,无需经过网络请求。

  • 缓存作用:减少请求次数,提高性能。

  • 实现方式:强制缓存、协商缓存

1、强制缓存

强制缓存:由浏览器决定是否使用缓存。

浏览器判断缓存是否过期,没过期则直接使用本地缓存。

示例:返回 200 状态码,size 项标识 from disk cache。👉 说明使用了强制缓存。

1.1、实现

两种实现方式,分别对应两个 HTTP 首部字段。

首部的含义是资源在客户端缓存的有效期

  1. Cache-Control(通用首部):相对时间,需要计算是否缓存过期。
  2. Expires(实体首部):绝对时间,可直接判断缓存过期。

如果响应报文的首部中同时有 Cache-Control 和 Expires,

Cache-Control 优先级更高

1.2、Cache-Control 🔥

Cache-Control 选项更多,设置更加精细,更推荐使用。

实现流程

  1. 浏览器第一次请求访问服务器资源。

  2. 服务器:返回资源,在响应报文的首部添加 Cache-Control(设置过期时间大小);

  3. 浏览器再次请求访问服务器中的该资源时

    • 结合请求时间与 Cache-Control 设置的过期时间计算资源是否过期,没过期则继续使用该缓存
    • 过期则重新请求服务器。
  4. 服务器:再次收到请求后,更新响应报文中首部的 Cache-Control

2、协商缓存

协商缓存:由服务端告知客户端是否可以使用缓存。

浏览器与服务端协商之后,根据协商结果来判断是否使用本地缓存。

示例:响应码 304 Not Modified。👉 服务器告诉浏览器可以使用本地缓存的资源。

2.1、基于时间实现

2.1.1、相关 HTTP 首部

  • Last-Modified(实体首部):代表响应资源的最后修改时间(更新时间)。
  • If-Modified-Since(请求首部):代表客户端要比较资源的 Last-Modified。

2.1.2、实现

  • 浏览器第一次请求访问服务器资源。
  • 服务器:返回资源,并在响应报文首部添加 Last-Modified
  • 浏览器:发现响应报文首部中有 Last-Modified,再次发起请求的时候带上 If-Modified-Since(值为响应报文的 Last-Modified 时间)
  • 服务器:收到请求后发现有 If-Modified-Since对比资源的更新时间Last-Modified
    • 如果当前更新时间较新(大):说明资源在客户端上次缓存之后又被改过,响应 200 OK 和最新资源,并在响应报文首部添加新的 Last-Modified
    • 否则说明资源无新修改,响应 304 告知浏览器走缓存

基于时间实现的协商缓存,可能会因为时间篡改导致不可靠。

2.2、基于唯一标识实现 🔥

此方式必须配合强制缓存Cache-Control 使用,

当强制缓存未命中时,才进行协商缓存

2.2.1、相关 HTTP 首部

  • Etag(响应首部):唯一标识响应资源。
  • If-None-Match(请求首部):代表客户端要比较资源的 Etag。

2.2.2、实现

  • 浏览器第一次请求访问服务器资源。
  • 服务器:返回资源,并在响应报文首部添加 Etag
  • 浏览器
    • :先检查强制缓存是否过期,没过期则使用强制缓存;过期则进行协商缓存(即以下的后续步骤)。
    • 协商:发现响应报文首部中有 Etag,再次发起请求时带上 If-None-Match(值为 Etag 值)
  • 服务器:收到请求后发现有 If-None-Match比对资源的 Etag
    • 如果 Etag 不同:说明资源改变,响应 200 OK 和最新资源,并在响应报文首部添加新的 Etag
    • 否则说明资源无改变,响应 304 告知浏览器走缓存

2.2.3、优先级

如果响应报文的首部中同时有 Last-Modified 和 Etag,

Etag 优先级更高:先判断 Etag 是否变化,再判断 Last-Modified。

原因:ETag 能解决 Last-Modified 难以解决的问题。

  • 即使文件内容不变,Last-Modified 也可能改变。👉 此时客户端认为文件改动,从而重新请求。
  • 文件可能在秒级以内修改的。👉 If-Modified-Since 的检查粒度是秒级,Etag 是毫秒级。
  • 👉 部分服务器无法精确获取文件的 Last-Modified

附:Cache-Control 指令参数

Cache-Control(通用首部字段)

  • 指令参数可选的。
  • 多个参数之间用 , 分隔。
  • 请求报文和响应报文中有相同的参数,且含义可能不同。

共有

  1. no-cache防止使用过期的缓存(而不是不缓存)
    • 请求报文:客户端不接收缓存过的响应,缓存服务器必须把请求转发给源服务器。
    • 响应报文:源服务器要求缓存服务器不对资源进行缓存。
  2. no-store不使用缓存
  3. max-age
    • 请求报文:客户端只接收缓存时间比 max-age 值小的缓存资源(0 表示缓存服务器需要将请求转发给源服务器)。
    • 响应报文:缓存服务器不对资源有效性再作确认(max-age 值为缓存资源的最长保存时间)。
  4. no-transform:缓存不能改变实体主体的媒体类型,用于防止压缩编码等操作。
  5. cache-extension:扩展 Cache-Control 的首部字段内的指令。

请求报文独有

  1. max-stale:即使缓存资源过期,也照常接收。
  2. min-fresh:客户端要求缓存服务器,返回指定时间以内的缓存资源。
  3. only-if-cached:请求的资源在缓存服务器的本地缓存时,客户端才要求其返回。
    (即如果缓存服务器中没有请求资源的缓存,则不会转发请求给源服务器)

响应报文独有

  1. public:任何用户都可以使用响应的缓存
  2. private:指定用户才能使用响应的缓存
    • 缓存服务器对特定用户提供资源缓存的服务
    • 对其它用户发送的请求,不会返回缓存
  3. s-maxage:与 max-age 相同,但是 s-maxage 仅用于多用户使用的公共缓存服务器。
  4. must-revalidate:要求代理在返回缓存资源之前,向源服务器再次验证缓存是否仍有效
  5. proxy-revalidate:类似 must-revalidate,但只适用于共享缓存,不影响私有缓存。
posted @ 2022-02-27 17:20  Jaywee  阅读(142)  评论(0编辑  收藏  举报

👇