66-http-17-通用首部字段Cache-Control

http-通用首部字段Cache-Control

概述

通过指定首部字段 Cache-Control 的指令,就能操作缓存的工作机制。

书写格式

指令的参数是可选的,多个指令之间通过“,”分隔。首部字段 CacheControl 的指令可用于请求及响应时。

Cache-Control: private, max-age=0, no-cache

分类

缓存请求指令

指令 参数 说明
no-cache 不使用缓存,缓存服务器必须把客户端请求转发给源服务器,在与源服务器进行新鲜度再验证之前,不能提供给客户端使用。
no-store 真正的不使用缓存,任何地方都不缓存请求或响应的任何内容。
max-age=60 必需 资源可缓存最大时间(相对时间:秒),即过期时间、保质期。
max-stale=60 可省略 缓存资源,只要仍处于 max-stale指定的时间(秒)内,即使过期也照常接收。缓存总时长为max-age和max-stale叠加。
min-fresh=60 必需 期望在指定时间内(未来60秒内)的响应保持新鲜
no-transform 代理不可更改媒体类型
only-if-cached 只从缓存获取资源,若有则返回,若无则504

缓存响应指令

指令 参数 说明
no-cache 缓存前必须先确认其有效性
no-store 不缓存请求或响应的任何内容
public 客户端、代理服务器都可利用缓存
private 仅发起请求的客户端可利用缓存
max-age=60 必需 针对源服务器,资源可缓存最大时间
s-maxage=60 必需 针对代理缓存服务器,资源可缓存最大时间
must-revalidate 可缓存但必须再向源服务器进行确认
proxy-revalidate 代理缓存服务器对缓存的响应有效性再进行确认
no-transform 代理不可更改媒体类型

详解

no-cache

使用 no-cache 指令的目的是为了防止从缓存中返回过期的资源。

客户端发送的请求中如果包含 no-cache 指令,则表示客户端将不会接收缓存过的响应。于是,“中间”的缓存服务器必须把客户端请求转发给源服务器。

如果服务器返回的响应中包含 no-cache 指令,那么缓存服务器不能对资源进行缓存。源服务器以后也将不再对缓存服务器请求中提出的资源有效性进行确认,且禁止其对响应资源进行缓存操作。

Cache-Control: no-cache

如果可以使用缓存,则304;不可以使用,则200。

max-age

客户端发送的请求中包含 max-age 指令时,如果判定缓存资源的缓存时间数值比指定时间的数值更小,那么客户端就接收缓存的资源。
另外,当指定 max-age 值为 0,那么缓存服务器通常需要将请求转发给源服务器

服务器返回的响应中包含 max-age 指令时,缓存服务器将不对资源的有效性再作确认,而 max-age 数值代表资源保存为缓存的最长时间。

Cache-Control: max-age=604800(单位:秒)

问题

有一个问题 catch-control 是客户端缓存,当max-age 之内,服务端更新了数据,客户端是不能知道的。

这个问题,前端的一种常用的解决方案是,将打包的js文件名加入一段哈希码,当打包内容不变时,哈希码就不变。这样子,当内容不变时,请求的url 也就不变,当内容变了请求的url 也变了。这样就达到了更新缓存的目的。

min-fresh

min-fresh 指令要求缓存服务器返回至少还未过指定时间的缓存资源。

比如,当指定 min-fresh 为 60 秒后,过了 60 秒的资源都无法作为响应返回了。

Cache-Control: min-fresh=60(单位:秒)

max-stale

使用 max-stale 可指示缓存资源,即使过期也照常接收。

如果指令中指定了具体数值,那么即使过期,只要仍处于 max-stale指定的时间内,仍旧会被客户端接收。

如果指令未指定参数值,那么无论经过多久,客户端都会接收响应;

Cache-Control: max-stale=3600(单位:秒)

only-if-cached

使用 only-if-cached 指令表示客户端仅在缓存服务器本地缓存目标资源的情况下才会要求其返回。换言之,该指令要求缓存服务器不重新加载响应,也不会再次确认资源有效性。若发生请求缓存服务器的本地缓存无响应,则返回状态码 504 Gateway Timeout。

Cache-Control: only-if-cached

must-revalidate

使用 must-revalidate 指令,代理会向源服务器再次验证即将返回的响应缓存目前是否仍然有效。

若代理无法连通源服务器再次获取有效资源的话,缓存必须给客户端一条 504(Gateway Timeout)状态码。

另外,使用 must-revalidate 指令会忽略请求的 max-stale 指令(即使已经在首部使用了 max-stale,也不会再有效果)。

Cache-Control: must-revalidate

proxy-revalidate

proxy-revalidate 指令要求所有的缓存服务器在接收到客户端带有该指令的请求返回响应之前,必须再次验证缓存的有效性。

Cache-Control: proxy-revalidate

no-transform

有时为了提高性能,缓存或代理会有压缩图片等类似操作

使用 no-transform 指令规定无论是在请求还是响应中,缓存都不能改变实体主体的媒体类型。
这样做可防止缓存或代理压缩图片等类似操作

浏览器缓存机制

以下总结自网络,以后确认具体过程。

1、当前缓存是否过期?2、服务器中的文件是否可用?

第一步:判断当前缓存是否过期

浏览器请求server.js文件,

假如文件还在缓存有效期内,则直接使用缓存,不会重新发起请求。

假如文件缓存过期,则重新发起请求。

第二步:判断服务器中的文件是否可用

服务器判断请求的server.js文件是否在缓存有效期内,若有效,则返回响应头304,浏览器直接使用过期缓存;

若文件已过期,服务器判断文件是否有改动,无改动,则返回响应头304,浏览器直接使用过期缓存;

若文件有改动,则返回200,并返回新文件。

cache-control使用图解

目前仍有的疑问

1、缓存总时长为max-age和max-stale叠加,取值为相加值,还是最大值?

2、must-revalidate和proxy-revalidate区别?

推荐阅读

Cache-Control - How to Properly Configure It