HTTP缓存

432 阅读5分钟

简要概括HTTP缓存过程


Date/Age响应头

Date:Date头域表示消息发送的时间,缓存在评估响应的新鲜度时要用到,时间的描述格式由RFC822定义。例如,Date: Thu, 11 Jul 2015 15:33:24 GMT。 

Age:Age告知客户端,源服务器在多久前创建了响应;若创建该响应的服务器是代理服务器,值为缓存后的响应再次发起认证到认证完成的时间值。

Cache-Control

请求体

1. max-age:告诉服务器,客户端不会接受Age超出max-age秒的缓存

    max-age = 0: 不管response怎么设置,在重新获取资源之前,先检验ETag/Last-Modified,和no-cache作用相同

2. max-stale:缓存过期后,陈旧秒数不超过max-stale仍然可以使用缓存,如果max-stale后面没有值,无论过期多久都可以使用缓存

3. min-fresh:缓存的资源至少要保持指定时间的新鲜期


假设所请求资源于4月5日缓存, 且在4月12日过期.

当max-age 与 max-stale 和 min-fresh 同时使用时, 它们的设置相互之间独立生效, 最为保守的缓存策略总是有效. 这意味着, 如果max-age=10 days, max-stale=2 days, min-fresh=3 days, 那么:

  • 根据max-age的设置, 覆盖原缓存周期, 缓存资源将在4月15日失效(5+10=15);

  • 根据max-stale的设置, 缓存过期后两天依然有效, 此时响应将返回110(Response is stale)状态码, 缓存资源将在4月14日失效(12+2=14);

  • 根据min-fresh的设置, 至少要留有3天的新鲜期, 缓存资源将在4月9日失效(12-3=9);

4. no-cache:强制向源服务器再次验证,端对端重载,不要使用代理服务器的缓存

5. no-store: 不缓存资源

6. only-if-cached:告诉服务器仅能返回缓存过的响应【服缓存服务器不重新加载响应,也不再次确认资源有效性】,没有缓存则返回504

7. no-transform: 强制要求代理服务器不要对资源进行转换, 禁止代理服务器对 Content-Encoding, Content-Range, Content-Type字段的修改(因此代理的gzip压缩将不被允许)


响应体

1. must-revalidate:如果缓存失效, 强制重新向服务器发起验证(因为max-stale等字段可能改变缓存的失效时间)

2. proxy-revalidate:与上述类似,但是仅对代理服务器的共享缓存有效

3. no-cache:告诉客户端不能直接使用缓存的响应,使用前必须在原服务器验证得到304。如果no-cache后指定头部,如no-cache=Set-Cookie,对于Set-Cookie以外的其他资源都可以使用缓存,而Set-Cookie字段必须使用最新的。

4. public:无论是私有缓存或者共享缓存,皆可将该响应缓存(注意隐私泄露)

5. private:该响应不能被代理服务器作为共享缓存使用,若private后指定头部,告诉代理服务器不能缓存指定的头部,但是可以缓存其他头部

6. no-store: 不能缓存资源

7. no-transform:告诉代理服务不要修改响应包体

8. max-age:缓存有效时间,过期就向服务器请求

9. s-maxage:针对共享缓存,优先级高于max-age


Location:URI

302:临时重定向

301:永久重定向,浏览器是由缓存的


协商缓存

ETag

强ETag:不论实体发生多小的变化,都会改变其值

偌ETag:开头加上 W/,资源发生根本变化,产生差异时才会改变ETag值


条件请求头部

if-Match

if-Match ='*' / entity-tag

 GET/HEAD + Range + if-Match,可以用来保证新请求的范围与之前请求的范围是对同一份资源的请求,ETag不满足条件返回416 (Range Not Satisfiable)

单独使用if-Match,满足条件执行请求,不满足条件返回412

PUT + if-Match,可以解决避免更新丢失的问题


if-None-Match

if-None-Match = '*' / entity-tag

E-Tag一致,验证失败,对于GET/HEAD返回304,其他(引起服务器状态改变的)方法返回412

E-Tage不一致,验证成功,返回200


if-Modified-Since 

if-Modified-Since = HTTP-date ONLY GET/HEAD

在指定时间后资源更新:满足条件返回200

否则:不满足返回304 与If-None-Match一同出现的时候会被忽略掉,除非服务器不支持If-None-Match 场景:更新没有特定Etag标签的实体


if-UnModified-Since

if-UnModified-Since = HTTP-date

在指定时间后资源未更新:返回资源,或者执行后续操作

在指定时间后资源更新:不满足条件,返回 412


if-Range

if-Range = entity-tag/HTTP-date

搭配Range使用,E-tag一致,满足条件,返回206(Partical Content)

如果不一致,返回全部资源 200 OK

字段值中既可以用 Last-Modified 时间值用作验证,也可以用ETag标记作为验证,但不能将两者同时使用

If-Range 头字段通常用于断点续传的下载过程中,用来自从上次中断后,确保下载的资源没有发生改变。


参考资料


1. www.cnblogs.com/zhoulujun/p…

2. 《图解HTTP》

3.  MDN