http 缓存控制

613 阅读4分钟

http 缓存

http缓存的知识点包括缓存控制和缓存校验 缓存属于http中条件请求的部分,相应的http头部有if-match if-no-match if-modified-since if-unmodified-since if-range

缓存控制 cache-control

缓存控制:控制缓存的开关,用于标识请求或访问中是否开启了缓存,使用了哪种缓存方式

客服端 请求头 cache-control

字段名称 说明
no-cache 告诉服务器,不能直接使用已有缓存作为响应返回,除非带着缓存条件到上游服务端得到 304 验证返回码才可使用现有缓存
no-store 所有内容都不会保存到缓存或internet临时文件
max-age=delta-seconds 告知服务器客户端希望接受一个存在时间不大于delta-seconds的资源,或者:告诉服务器,客户端不会接受 Age 超出 max-age 秒的缓存
max-stale[=delta-seconds] 告知代理服务器客户端愿意接受一个超过缓存时间的资源,若有定义delta-seconds,则为相应秒数,否则则为任意超出时间
min-fresh=delta-seconds 告知(代理)服务器,客户端希望接受一个更新时间小于delta-seconds的资源
no-transform 告知(代理)服务器,客户端希望获取实体数据没有被转换过的资源(比如被压缩)
only-if-cached 告诉(代理)服务器仅能返回缓存的响应,否则若没有缓存则返回 504 错误码
cache-extension 自定义拓展值,若服务器不识别,则被忽略掉

服务端 返回值 cache-control

字段名称 说明
public 任何情况下都得缓存资源(即使是需要http认证的资源
private[="feild-name"] 表明返回资源的全部或部分(若指定了feild-name,则为feild-name的字段数据)仅开放给某些用户(服务器指定的share-user 如代理服务器)做缓存使用,其他用户则不能缓存这些数据,表示该响应不能被代理服务器作为共享缓存使用。若 private 后指定头部,则在告诉代理服务器不能缓存指定的头部,但可缓存其他部分
no-cache 告诉客户端不能直接使用缓存的响应,使用前必须在源服务器验证得到 304 返回码。如果 no-cache后指定头部,则若客户端的后续请求及响应中不含有这些头则可直接使用缓存
no-store 告诉所有下游节点不能对响应进行缓存
no-transform 告知客户端缓存文件不得对实体数据作出改变
only-if-cached
must-revalidate 当前资源一定是向原服务器发去验证请求的,若请求失败,返回504,而非代理服务上缓存
proxy-revalidate 与must-revalidate类似,但只能用于共享缓存
max-age=delta-seconds 告诉客户端缓存 Age 超出 max-age 秒后则缓存过期
s-max-age=delta-seconds 同max-age,但只能用于共享缓存(如代理)

缓存校验

缓存校验:如何校验缓存,比如怎么定义缓存的有效期,怎么确保缓存是最新的

在缓存中,我们需要一个机制来验证缓存是否有效。比如服务器的资源更新了,客户端需要及时刷新缓存;又或者客户端的资源过了有效期,但服务器上的资源还是旧的,此时并不需要重新发送。缓存校验就是用来解决这些问题的,在http 1.1 中,我们主要关注下Last-Modified 和 etag 这两个字段。

Last-Modified

服务端在返回资源时,会将该资源的最后更改时间通过Last-Modified字段返回给客户端。客户端下次请求时通过If-Modified-Since或者If-Unmodified-Since带上Last-Modified,服务端检查该时间是否与服务器的最后修改时间一致:如果一致,则返回304状态码,不返回资源;如果不一致则返回200和修改后的资源,并带上新的时间。 If-Modified-Since和If-Unmodified-Since的区别是: If-Modified-Since:告诉服务器如果时间一致,返回状态码304 If-Unmodified-Since:告诉服务器如果时间不一致,返回状态码412

Etag

单纯的以修改时间来判断还是有缺陷,比如文件的最后修改时间变了,但内容没变。对于这样的情况,我们可以使用etag来处理。 etag的方式是这样:服务器通过某个算法对资源进行计算,取得一串值(类似于文件的md5值),之后将该值通过etag返回给客户端,客户端下次请求时通过If-None-Match或If-Match带上该值,服务器对该值进行对比校验:如果一致则不要返回资源。 If-None-Match和If-Match的区别是: If-None-Match:告诉服务器如果一致,返回状态码304,不一致则返回资源 If-Match:告诉服务器如果不一致,返回状态码412