HTTP Header of Cache-Control

2020-12-29  本文已影响0人  莫帆海氵

常见的有以下几种设置

// 不使用缓存
Cache-Control: no-cache
// 不使用缓存,缓存有效期 0
Cache-Control: max-age=0
// 不使用缓存
Cache-Control: no-store, max-age=0
// 使用缓存,缓存有效期 120s
Cache-Control: max-age=120

它在 HTTP header 中设置,用于控制请求和响应的缓存相关内容,同一个请求中请求头和响应头中不一定会一样,就是请求头设置什么响应头就要返回什么。

常用的值有:

no-store
no-cache
max-age=<seconds>
must-revalidate
private
public
...

它的值可以分为以下三类

  1. 缓存能力 Cacheability
  2. 有效期 Expiration
  3. 校验和重载 Revalidation and reloading

缓存可以分别设置这三部分内容,可以互相独立,也可以多个一起设置,他们分别用于控制是否存储缓存、缓存的有效期时长以及使用缓存前是否必须向服务器发起校验。

缓存能力

* no-store
* no-cache
* private
* public

有效期

* max-age=<seconds>
* min-fresh=<seconds>
* max-stale[=<seconds>]

校验和重载

* must-revalidate
* immutable

no-store

响应不会存储在任何缓存中,它不会影响应已缓存过的内容。也就是新请求不会缓存,不会影响上一次缓存的结果。

假设有下面的请求过程

  1. 假设有个请求 A,它的响应头 cache-control=max-age=100
  2. 先请求一次 A,会在本地存储缓存
  3. 更改 A 的响应头 cache-control=no-store
  4. 再次发起请求 A,依然获取的是缓存的内容
  5. 可以通过设置 A 的请求头 cache-control=max-age=0 来获取非缓存内容

no-cache

响应可能存储在任何缓存中,只是在使用缓存前必须通过远程服务器校验一次。这个指令不是用来阻止缓存存储你的响应内容的。

可以理解为不使用缓存,每次请求都会校验缓存是否还是新的,是则继续使用缓存内容(不会在下载),否则重新下载内容。

private

响应只能被浏览器缓存存储。

public

响应可能被任何缓存存储

如果你想不让任何缓存存储你的响应内容,可以使用 no-store

max-age

用来设置资源被视为新鲜的最长时间

must-revalidate

指示一旦资源过期了,缓存在没有通过远程服务器校验成功之前不能使用旧的副本

小结

Cache-Control: no-cache

不使用缓存,响应内容会存储在缓存中,但每次请求都会重新向远程服务器发起校验

Cache-Control: max-age=0

不使用缓存,缓存也会存储,有效期为 0 则每次请求都会向远程服务器发起校验,只是在服务器挂掉或者连接失败的时候还会使用缓存内容。

Cache-Control: no-store, max-age=0

不使用缓存,响应内容不会存储,no-store 新的请求不会缓存,max-age=0 保证每次请求都会校验

Cache-Control: max-age=120

使用缓存,缓存会存储,超过有效期后会向远程服务器发起校验。

Other

Cache-Control: no-cache 和 Cache-Control: max-age=0, must-revalidate 设置的作用是一致的

如果要阻止缓存需要设置 Cache-Control: no-store, max-age=0

问题

1 如何清空一个请求的缓存,使用最新的响应内容?(本地已经有存在的缓存)

假如有一个请求设置为 Cache-Control: max-age=3600,如何清空这个缓存?

方法一:在发起请求是设置标头 Cache-Control: no-cache 或者 max-age=0(需要在客户端增加)

TODO 如果不更改客户端能更新缓存吗?
可以通过设置响应头 Clear-Site-Data,它可以清空当前域下的缓存、cookie、本地存储等,但它目前只在草稿阶段,safari 手机端和 pc 端都不支持。

Clear-Site-Data: "cache", "cookies", "storage", "executionContexts"

参考 https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Clear-Site-Data

2 缓存可以存储在哪些地方?

缓存可以分为本地和共享两大类,本地,eg: 本地浏览器,共享,eg: 代理,网关。

3 怎么检测一个缓存还是有效的?

简而言之就是检查缓存是否是新鲜的,也就是看过期时间,没有超过过期时间就是有效的缓存。

计算缓存的新鲜寿命(freshnessLifetime)

  1. 如果响应有 max-age 标头,它的值就是缓存的寿命
  2. 如果响应有 Expires 标头,用它的值减去响应的 header 标头的值就是缓存的寿命
  3. 其它使用默认的 Heuristic 算法计算缓存的寿命
expirationTime = responseTime + freshnessLifetime - currentAge

基于以上可以计算一个缓存的过期时间 = 接收到响应的时间 + 缓存寿命 - 当前请求时间,只要计算的缓存过期时间大于 0 则缓存就是有效的。

也就是每个新的请求过来,用当前请求的时间代入计算,过期时间大于 0 则可以继续使用缓存。

上一篇下一篇

猜你喜欢

热点阅读