前端缓存学习笔记(1)

113 阅读5分钟

强制缓存

Expires

Expires 首部字段是 HTTP/1.0 中定义缓存的字段,其给出了缓存过期的绝对时间,即在此时间之后,响应资源过期,属于实体首部字段

示例

Expires: Wed, 11 May 2022 03:50:47 GMT

上述示例表示该资源将在以上时间之后过期,而在该时间之前浏览器可以直接从浏览器缓中读取数据,无需再次请求服务器。注意这里无需再次请求服务器便是命中了强缓存。

但是因为 Expires 设置的缓存过期时间是一个绝对时间,所以会受客户端时间的影响而变得不精准。

Cache-Control

Cache-Control 首部字段是 HTTP/1.1 中定义缓存的字段,其用于控制缓存的行为,可以组合使用多种指令,多个指令之间可以通过 “,” 分隔,属于通用首部字段。常用的指令有:max-age、s-maxage、public/private、no-cache/no store 等。

当 客 户 端 请 求 头 中 包 含Cache-Control:max-age=0 请求,明确表示不会缓存服务器资源时,Cache-Control 作为作为回应信息,通常会返回 no-cache,意思就是说,“那就是不缓存”。

当客户端在请求头中没有包含 Cache-Control 时,服务端往往会定,不同的资源不同的缓

存策略,比如说 oschina 在缓存图片资源的策略就是 Cache-Control:max-age=86400,这个意思是,从当前时间开始,在 86400 秒的时间内,客户端可以直接从缓存副本中读取资源,而不需要向服务器请求。

示例

Cache-Control: max-age:3600, s-maxage=3600, public
Cache-Control: no-cache

max-age 指令给出了缓存过期的相对时间,单位为秒数。当其与 Expires 同时出现时,max-age 的优先级更高。但往往为了做向下兼容,两者都会经常出现在响应首部中。

同时 max-age 还可在请求首部中被使用,告知服务器客户端希望接收一个存在时间(age)不大于多少秒的资源。

而 s-maxage 与 max-age 不同之处在于,其只适用于公共缓存服务器,比如资源从源服务器发出后又被中间的代理服务器接收并缓存。

no-cache 和 no-store

no-cache:先与服务器确认返回的响应是否发生了变化,然后才能使用该响应来满足后续对同一网址的请求。因此,如果存在合适的验证令牌 (ETag),no-cache 会发起往返通信来验证缓存的响应,但如果资源未发生变化(即If-None-Match是否为true),则可避免下载

no-store:直接禁止浏览器以及所有中间缓存存储任何版本的返回响应,例如,包含个人隐私数据或银行业务数据的响应。每次用户请求该资产时,都会向服务器发送请求,并下载完整的响应

public 和 private

public:指令表示该资源可以被任何节点缓存(包括客户端和代理服务器)

private:该资源只提供给客户端缓存,代理服务器不会进行缓存。同时当设置了 private 指令后 s-maxage 指令将被忽略

协商缓存

Last-Modified 与 If-Modified-Since

Last-Modified 首部字段顾名思义,代表资源的最后修改时间,其属于响应首部字段。当浏览器第一次接收到服务器返回资源的 Last-Modified 值后,会把这个值存储起来,并再下次访问该资源时通过携带 If-Modified-Since 请求首部发送给服务器验证该资源有没有过期。

Last-Modified 是服务端发给客户端

If-Modified-Since 是客户端发给服务端

示例

Last-Modified: Fri , 14 May 2021 17:23:13 GMT
If-Modified-Since: Fri , 14 May 2021 17:23:13 GMT

Etag 与 If-None-Match

Etag 首部字段用于代表资源的唯一性标识,服务器会按照指定的规则生成资源的标识,其属于响应首部字段。当资源发生变化时,Etag 的标识也会更新。同样的,当浏览器第一次接收到服务器返回资源的 Etag 值后,其会把这个值存储起来,并在下次访问该资源时通过携带 If-None-Match 请求首部发送给服务器验证该资源有没有过期。

Etag 是服务端发给客户端

If-None-Match 是客户端发给服务端

示例

Etag: "29322-09SpAhH3nXWd8KIVqB10hSSz66"
If-None-Match: "29322-09SpAhH3nXWd8KIVqB10hSSz66"

如果服务器发现 If-None-Match 值与 Etag 不一致时,说明服务器上的文件已经被更新,那么服务器会发送更新后的资源给浏览器并返回最新的 Etag 值,浏览器收到资源后会更新缓存的 If-None-Match 的值。

协商缓存流程

  1. 客户端发起一个请求A资源
  2. 服务端返回A资源,并给A加上一个Last-Modified/ETag
  3. 客户端再次请求A资源,带上次存储 If-Modified-Since/If-None-Match
  4. 服务器检查该 If-Modified-Since/If-None-Match和Last-Modified/ETag进行对比,判断资源是否被修改直接返回响应304和一个空的响应体。