Http 缓存

当只读请求 (GET/HEAD) 的数据在一段时间内是相同的,那么在客户端上对数据进行存储复用将能够大大系统的响应速度,这就是 Http 缓存的由来。

https://httpwg.org/specs/rfc7234.html


缓存从位置上可分为四种,各自有使用场景,并且各自有优先级。

  • Service Worker
  • Memory Cache
  • Disk Cache
  • Push Cache

具体可参考: https://www.jianshu.com/p/54cc04190252


缓存从类型上来区分,可分为 强缓存协商缓存。强缓存是不需要发送 HTTP 请求的,而协商缓存需要请求服务端,强缓存优先于协商缓存。


强缓存

当缓存可用时不需要发送 HTTP 请求的,浏览器将直接返回 200 响应,并标明数据来源。

Expires

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Expires

是 http/1.0 提出的规范,代表这个资源将于指定时间后过期。

Expires: Wed, Nov 30 2020 20:00:00 GMT

这个资源将在 2020年11月30日20点 过期,但是这个资源是否过期将受限于当前客户端的系统时间。

Cache-Control

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Cache-Control

为了解决 Expires 所存在的问题,http/1.1 出现了 Cache-Control,使用相对时间作为缓存时间,它的优先级在 Expires 之上,

Pragma

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Pragma

http/1.0 遗留的缓存标准,现已废弃。

协商缓存

当强缓存失效后,浏览器携带缓存标识发送请求到服务端,当本地缓存有效时将返回 304 响应.

Last-Modified

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Last-Modified

它是一个响应头,返回的是资源的修改时间,通常被用作一个验证器来判断接收到的或者存储的资源是否彼此一致,最低精度为秒。

GETHEAD 请求中,使用 If-Modified-Since 这个请求头进行验证。

POST 或其他不安全请求方法中,使用 If-Unmodified-Since 来进行验证。

Etag

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/ETag

Etag 响应头返回的是资源在服务端的版本标识符,它能解决 Last-Modified 在精度上的不足,通过对响应内容进行编码得出版本号进行对比。

GETHEAD 方法来说,请求头中需包含 If-None-Match 来对内容进行比对。

Java 的 Spring 框架中提供的 org.springframework.web.filter.ShallowEtagHeaderFilter 就是对这一流程进行了实现。


工作流程

alt 缓存工作流程

Vary

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Vary

对于一些区分客户端数据响应的场景,Vary就能够对不同的客户端进行区分缓存。

参考:
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Caching_FAQ https://jakearchibald.com/2017/h2-push-tougher-than-i-thought/