本篇讲解OKhttp的缓存机制,在网络请求中能合理地利用本地缓存可以减少网络开销,提高响应速度。Http报头定义了很多有关控制缓存策略的域,因为OKhttp的缓存机制终究也是基于Http的缓存策略来实现的,所以我们先来认识一下Http的缓存策略
一.HTTP缓存策略
Http缓存有多种规则,根据是否需要向服务器发起请求将缓存分为两大类:强制缓存和对比缓存
强制缓存是服务器会给客户端一个资源的到期时间,下一次请求时,如果请求时间小于到期时间,那么就直接使用缓存, 否则请求服务器,Http中用来判断是否命中强缓存的字段为Expires和Cache-Control,Cache-Control优先级高于Expires
对比缓存是需要经过服务器返回信息才能确认是否使用缓存的机制,所以对比缓存并不能降低服务器的请求次数,但能减小请求的负荷,明显提升请求速度和节省网络带宽,Http中判断对比缓存的字段有Last-Modified / If-Modified-Since和ETag/If-None-Match,后者优先级高于前者
强制缓存的状态码为200,对比缓存的状态码为304,如果同时存在强制缓存和对比缓存,那么强制缓存的优先级大于对比缓存
1.1 Expires
expires字段是HTTP 1.0 时代的产物了,是服务器返回的资源的到期时间,在下一次请求时,如果请求时间小于这个到期时间,那么就直接使用缓存,否则重新请求,当然如果客户端时间和服务器时间有差异的话也会产生误差,所以在HTTP/1.1基本上不使用expires了,而是使用Cache-Control代替
1.2 Cache-Control
Cache-Control的优先级比Expires高,其中no-cache和no-store表示不缓存,max-age表示缓存时间,单位为秒,比如max-age=7200表示2小时内再次请求这条数据时,就直接使用缓存,比如下面响应头信息
Cache-Control字段的内容有很多种,除了cache-control:public,max-age ,Cache-Control还有很多其他字段,如下
Cache-Control 常见字段的含义:
public | 表明响应可以被任何对象(包括:发送请求的客户端,CDN等代理服务器,等等)缓存,即使是通常不可缓存的内容(例如,该响应没有max-age指令或Expires消息头) |
private | 表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它),私有缓存可以缓存响应内容 |
no-cache | 可以在本地进行缓存,但每次发请求时,都要向服务器进行验证,如果服务器允许,才能使用本地缓存(即需要协商缓存) |
no-store | 禁止缓存客户端请求或服务器的响应内容,每次都须重新请求服务器获取资源 |
max-age | 设置缓存存储的最大周期,超过这个时间缓存被视为过期 (单位:秒) |
only-if-cached | 不进行网络请求,完全只使用缓存,若缓存不命中,则返回503错误 |
1.3 Last-Modified / If-Modified-Since
这是对比缓存的字段,Last-Modified 代表这个资源最后的修改时间,如图
客户端下次请求这条数据的时候,会在请求头的If-Modified-Since字段带上这个最后修改时间,代表客户端缓存数据的最后修改时间,如下
当服务器接收到客户端的请求,将对比客户端缓存数据的最后修改时间和自己保存的最后修改时间,如果它们相等,就代表数据没有被修改过,此时响应状态码为304,告诉客户端可以使用缓存,否则返回新数据给客户端
1.4 ETag/If-None-Match(优先级高于Last-Modified/If-Modified-Since)
ETag是服务器返回给客户端的一个唯一标识(生成规则由服务器决定)
客户端再次请求时,可以在请求头的If-None-Match字段加上这个标识