一、Cache-Control介绍
Cache-Control通用标头字段用于指定所有请求/响应链上的缓存机制必须遵守的一个指令。这些指令通常会覆盖默认的缓存算法。在HTTP/1.0中,可能不会实现Cache-Control,而只支持Pragma: no-cache。
代理或应用网关必须传递缓存指令,不论它们是否能够生效,因为缓存指令可能被响应、请求链上任一的设备识别并生效。
请求头中Cache-Control可用的值:
no-cache, no-store, max-age, max-stale, min-fresh, no-transform, only-if-cached, cache-extension
响应头中Cache-Control可用的值:
public, private, no-cache, no-store, no-transform, must-revalidate, proxy-revalidate, max-age, s-maxage
二、Cache-Control各个指令的含义
public
任何的缓存都可以缓存响应。
private
表示响应内容全部或部分包含用户个人的信息,不能被缓存在公共缓存中。但私有缓存可以对响应进行缓存。
no-cache
如果no-cache后面没有指定字段名,那么缓存绝不能不与原始服务器进行资源新鲜度检查就直接返回响应。这是避免源服务器返回陈旧的数据,即使中间配置了缓存。
如果no-cache后面指定了一个或多个字段名,那么缓存可以进行响应,但受缓存的其他限制。但在没有向原始服务器重新验证的情况下,不能发送指定字段名称。这允许源服务器阻止响应中使用某些字段,但其余部分可以缓存。
HTTP/1.0的缓存不认识,也不会遵从该指令。
no-store
no-store指令的目的是为了防止无意泄露或保留的敏感信息(如在磁盘上)。no-store适用于整条消息,可以在请求或响应中发送。如果在请求中发送,则缓存绝不能将请求及对应的响应的内容保存。如果在响应中发送,则缓存绝不能存储该响应的任何部分以及由该响应引发的其他请求。该指令适用于共享缓存以及非共享缓存。上文“绝不能保存”的含义是缓存不能故意将内容存在非易失存储中,并尽量在转发之后立即从易失存储中删除。
max-age
表示客户端希望接受年龄不超过指定秒数的响应。除非有max-stale指令,否则客户端不愿意接受陈旧的响应。
min-fresh
表示客户端愿意接受其新鲜度生命周期不小于其当前年龄加上指定时间(秒)的响应。 也就是说,客户端想要的响应至少在指定的秒数内仍然是新鲜的。
max-stale
表示客户端愿意接受超过其到期时间的响应。 如果为max-stale分配了值,则客户端愿意接受超过其到期时间的响应不超过指定的秒数。 如果没有为max-stale分配值,则客户愿意接受任何年龄的陈旧响应。
only-if-cached
在某些情况下,例如网络连接极差的情况,客户端可能希望缓存仅返回它当前存储的响应,而不是使用源服务器重新加载或重新验证。 为此,客户端可以在请求中包含only-if-cached指令。如果它收到此指令,则缓存应该使用与请求的其他约束一致的缓存条目进行响应,或者使用504(网关超时)状态进行响应。 但是,如果一组高速缓存作为具有良好内部连接的统一系统运行,则可以在该组高速缓存中转发这样的请求。
must-revalidate
缓存必须验证资源的过期状态,不能使用过期的资源。
三、HTTP默认缓存策略
除非受Cache-Control指令的特别限制,否则缓存系统可能总是将成功的响应存储为缓存条目,如果是新的响应则可以直接返回而不进行验证,也可以在成功验证后返回它。 如果既没有缓存验证器也没有与响应关联的显式过期时间(如Expires、age等),我们不希望它被缓存,但某些缓存可能违反此期望(例如,当很少或没有可用的网络连接时)。 客户端通常可以通过将Date标头与当前时间进行比较来检测是否从缓存中获取了此类响应。
200, 203, 206, 300, 301 以及 410响应码可被缓存并返回给客户端,但如果不支持Range和Content-Range头的缓存不能缓存206状态码的响应。
其他状态码(如302)在没有明确的缓存指令时,绝不能进行缓存。