在了解OkHttp
的缓存实现以前,咱们先来复习一下HTTP
协议当中,与缓存有关的一些基础知识,这里,咱们会介绍HTTP
中与缓存相关的首部字段,根据首部字段的做用,能够将其分为如下四类:java
Cache-Control
If-Match
、If-Modified-Since
、If-None-Match
、If-Range
、If-Unmodified-Since
。ETag
Last-Modified
在通用首部字段中,与缓存有关的字段为Cache-Control
。Cache-Control
是HTTP/1.1
的通用首部字段,经过指定它的值,就可以操做缓存的工做机制。指令的参数是可选的,多个指令之间经过","
分隔,首部字段Cache-Control
的指令可用于 请求及响应 时。算法
Cache-Control : private, max-age=0, no-cache
复制代码
指令 | 说明 |
---|---|
no-cache |
强制向源服务器再次验证 |
no-store |
不缓存请求或响应的任何内容 |
max-age=[s] |
响应的最大age 值 |
max-stale=[s] |
接收已过时的响应 |
min-fresh=[s] |
指望在指定时间内的响应仍然有效 |
no-transform |
代理不可更改媒体类型 |
only-if-cached |
从缓存获取资源 |
cache-extension |
新指令标记 |
指令 | 说明 |
---|---|
public |
可向任意方提供响应的缓存 |
private |
仅向特定用户返回响应 |
no-cache |
缓存前必须先确认其有效性 |
no-store |
不缓存请求或响应的任何内容 |
no-transform |
代理不可更改媒体类型 |
must-revalidate |
可缓存但必须再向源服务器确认 |
proxy-revalidate |
要求中间缓存服务器对缓存的响应有效性再进行确认 |
max-age=[s] |
响应的最大age |
s-maxage=[s] |
公共缓存服务器响应的最大age |
cache-extension |
新指令标记 |
Cache-Control : public
复制代码
当指定使用public
指令时,则明确表示其它用户也能够利用缓存。缓存
Cache-Control : private
复制代码
当指定private
指令时,响应只以特定的用户做为对象,这与public
指令的行为相反,缓存服务器会对该特定的用户提供资源缓存的服务,对于其余用户发送过来的请求,代理服务器则不会返回缓存。bash
Cache-Control : no-cache
复制代码
使用no-cache
的指令的目的是为了 防止从缓存中返回过时的资源。服务器
客户端发送的请求 中若是包含no-cache
指令,则表示客户端将不会接收缓存过的指令。因而,“中间”缓存服务器必须把客户端请求转发给源服务器。spa
服务器返回的响应 中包含no-cache
指令,那么缓存服务器不能对资源进行缓存,源服务器之后也将再也不对缓存服务器请求中提出的资源有效性进行确认,且禁止缓存服务器对响应资源进行缓存操做。代理
Cache-Control : no-cache=Location
复制代码
由服务器返回的响应中,若报文首部字段Cache-Control
中对no-cache
字段名具体制定参数值,那么客户端在接收到这个被指定参数值的首部字段对应的响应报文后,就不能使用缓存,换言之,无参数值的首部字段可使用缓存,只能在响应指令中指定该参数。code
Cache-Control : no-store
复制代码
当使用no-store
指令时,暗示请求(和对应的响应)或响应中包含机密信息,所以,该指令规定缓存不能在本地存储请求或响应的任一部分。orm
它和no-cache
的区别在于,no-cache
表明 不缓存过时的资源,而no-store
是 真正的不缓存。cdn
Cache-Control : s-maxage=604800 (秒)
复制代码
s-maxage
和max-age
指令的功能相同,它们的不一样点是s-maxage
指令只适用于供多位用户使用的公共缓存服务器,也就是说,对于向同一用户重复返回响应的服务器来讲,这个指令没有任何做用。
另外,当使用s-maxage
指令后,则直接忽略对Expires
首部字段及max-age
指令的处理。
Cache-Control : max-age=604800 (秒)
复制代码
当 客户端发送的请求 中包含max-age
指令时,若是断定缓存资源的缓存时间数值比指定时间的数值更小,那么客户端就接收缓存的资源。另外,当指定max-age
值为0
时,那么缓存服务器一般须要将请求转发给源服务器。
当 服务器返回的响应 中包含max-age
指令时,缓存服务器将不对资源的有效性再作确认,而max-age
数值表明资源保存为缓存的最长时间。
在HTTP/1.1
版本中,会优先处理max-age
指令,而忽略Expires
首部字段。
Cache-Control : min-refresh=60 (秒)
复制代码
min-refresh
指令要求缓存服务器返回 至少还未过指定时间的缓存资源。好比,当指定min-refresh
为60s
后,在这60s
之内若是有超过有效期限的资源都没法做为响应返回了。
Cache-Control : max-stale=3600 (秒)
复制代码
使用max-stale
可指示缓存资源,即便过时也照常接收。若是指令未指定参数,那么不管多久,客户端都会接收响应;若是指令中指定了具体数值,那么即便过时,只要仍处于max-stale
指定的时间内,仍旧会被客户端接收。
Cache-Control : only-if-cached
复制代码
使用only-if-cached
指令表示客户端 仅在缓存服务器本地缓存目标资源的状况下才会要求其返回。换言之,该指令要求缓存服务器不从新加载响应,也不会再次确认资源有效性。若发生请求缓存服务器的本地缓存无响应,则返回504
。
Cache-Control : must-revalidate
复制代码
使用must-revalidate
指令,代理会 向源服务器再次验证即将返回的响应缓存目前是否仍然有效。
若代理没法连通源服务器再次获取有效资源的话,缓存必须给客户一条504
状态码。
另外,使用must-revalidate
指令会忽略请求的max-stale
指令。
Cache-Control : proxy-revalidate
复制代码
proxy-revalidate
指令要求全部的缓存服务器在接收到客户端带有该指令的请求返回响应以前,必须再次验证缓存的有效性。
Cache-Control : no-transform
复制代码
使用no-transform
指令规定不管是在请求仍是响应中,缓存都不能改变主体的媒体类型。这样作可防止缓存或代理压缩图片等相似操做。
在请求首部字段中,与缓存相关的字段为If-XXX
,像这种样式的请求首部字段,也称为条件请求,服务器接收到附带条件的请求后,只有判断指定条件为真时,才会执行请求。
首部字段If-Match
会告诉服务器匹配资源所用的实体标记ETag
。服务器会比对ETag
的字段值与资源的ETag
值,仅当二者一致时,才会执行请求,反之则返回状态码412
。
还可使用*
指定If-Match
的字段值,针对这种状况,服务器将会忽略ETag
的值,只要资源存在就处理请求。
If-Modified-Since
会告知服务器若字段值早于资源的更新时间,则但愿处理该请求,反之,则返回状态码
304
。
If-Modified-Since
用于确认代理或客户端拥有的本地资源的有效性,获取资源的更新日期时间,可经过确认首部字段Last-Modified
。
If-Match
做用相反。
和If-Modified-Since
做用相反。
首部字段ETag
能告知客户端实体标识。它是一种可将资源以字符串形式作惟一性标识的方式。服务器会为每份资源分配对应的ETag
值。
另外,当资源更新时,ETag
值也须要更新。生成ETag
值时,并无统一的算法规则,而仅仅是由服务器来分配。
ETag
值,不管实体发生多么细微的变化都会改变其值。ETag
值,只用于提示资源是否相同。只有资源发生了根本改变,产生差别时才会改变ETag
的值。首部字段Last-Modified
指明资源最终修改的时间。通常来讲,这个值就是Request-URI
指定资源被修改的时间。但相似使用CGI
脚本进行动态数据处理时,该值有可能会变成数据最终最终修改时的时间。