默认的缓存策略, 如果缓存不存在,直接从服务端获取。如果缓存存在,会根据response中的Cache-Control字段判断下一步操作,如: Cache-Control字段为must-revalidata, 则询问服务端该数据是否有更新,无更新的话直接返回给用户缓存数据,若已更新,则请求服务端.他是有服务器决定客户端到底是用缓存还是不用缓存,根据Cache-Control来确定,如果过期或者数据被改动就不用缓存,直接加载服务端数据,一般在Get方法中才使用到缓存,Post她变化比较多一般不使用缓存。
Tips: URL Loading System默认只支持如下5中协议: 其中只有http://和https://才有缓存策略.
缓存策略CachePolicy
useProtocolCachePolicy:默认缓存策略,对于特定URL使用网络协议中实现的缓存策略。
reloadIgnoringLocalCacheData(或者reloadIgnoringCacheData):不使用缓存,直接请求原始数据。
returnCacheDataElseLoad:无论缓存是否过期,有缓存则使用缓存,否则重新请求原始数据。
returnCacheDataDontLoad:无论缓存是否过期,有缓存则使用缓存,否则视为失败,不会重新请求原始数据。
其实对于多数开发者而言,第二种根本不缓存,其他两种也存在着很大的使用风险,所以默认缓存策略才是我们最关心的,它使用网络协议中实现的缓存策略,那我们就应该首先弄清网络协议中的缓存策略是如何来控制的(注意:无论是NSURLConnection还是NSURLSession都支持多种协议,这里重点关注HTTP、HTTPS)。
HTTP的请求和响应使用headers来进行元数据交换,例如MIME、Encoding,当然也包括缓存执行,下面会着重介绍相关缓存配置。
请求头信息 Request cache headers
If-Modified-Since:与响应头Last-Modified相对应,其值为最后一次响应头中的Last-Modified。
If-None-Match:与响应头Etag相对应,其值为最后一次响应头中的Etag。
响应头信息 Response cache headers
Last-Modified:资源最近修改时间
Etag:(Entity tag缩写)是请求资源的标识符,主要用于动态生成、没有Last-Modified值的资源。
Cache-Control:缓存控制,只有包含此设置可能使用默认缓存策略。可能包含如下选项:
max-age:缓存时间(单位:秒)。
public:可以被任何区缓存,包括中间经过的代理服务器也可以缓存。通常不会被使用,因为 max-age已经表示此响应可以缓存。
private:只能被当前客户端缓存,中间代理无法进行缓存。
no-cache:必须与服务器端确认响应是否发生了变化,如果没有变化则可以使用缓存,否则使用新请求的响应。
no-store:禁止使用缓存
Vary:决定如何决定请求是否可以使用缓存,通常用于缓存key唯一值确定因素,同一个资源不同的Vary设置会被作为两个缓存资源(注意,NSURLCache会忽略Vary请求缓存)。
注意:Expires是HTTP 1.0标准缓存控制,不建议使用,请使用Cache-Control:max-age代替,类似的还有Pragma:no-cache和Cache-Control:no-cache。此外,Request cache headers中也是可以包含Cache-Control的,例如如果设置为no-cache则说明此次请求不要使用缓存数据作为响应。
默认缓存策略下当客户端发起一个请求时首先会检查本地是否包含缓存,如果有缓存则继续检查缓存是否过期(通过Cache-Control:max-age或者Expires),如果没有过期则直接使用缓存数据。如果缓存过期了,则发起一个请求给服务器端,此时服务器端对比资源Last-Modified或者Etags(二者都存在的情况下下如果有一个不同则认为缓存已过期),如果不同则返回新数据,否则返回304 Not Modified继续使用缓存数据(客户端可以再使用"max-age"秒缓存数据)。在这个过程中可以发现,客户端发送不发送请求主要看max-age是否过期,而过期后是否继续访问则需要重新发起请求,服务器端根据情况通知客户端是否可以继续使用缓存(这个过程是必须请求的,只是返回结果可能是200或者304)。
清楚了默认网络协议缓存相关的设置之后,要使用默认缓存就很简单了,通常对于NSURLSession你不做任何设置,只要服务器端响应头部加上Cache-Control:max-age:xxx就可以使用缓存了。