文件下載的緩存策略
文件緩存:ETag或Last-Modified判斷文件緩存是否有效
如果服務器端的資源沒有變化,則自動返回 HTTP 304 (Not Changed.)狀態碼,內容為空,這樣就節省了傳輸數據量。當服務器端代碼發生改變或者重啟服務器時,則重新發出資源,返回和第一次請求時類似。從而保證不向客戶端重復發出資源,也保證當服務器有變化時,客戶端能夠得到最新的資源。Last-Modified
是資源最後修改的時間戳,往往與緩存時間進行對比來判斷緩存是否過期。
ETag
是的功能與 Last-Modified
類似:服務端不會每次都會返回文件資源。客戶端每次向服務端發送上次服務器返回的 ETag
值,服務器會根據客戶端與服務端的 ETag
HTTP
狀態碼。客戶端通過 HTTP
狀態碼來決定是否使用緩存。比如:服務端與客戶端的 ETag
值相等,則 HTTP
狀態碼為 304,不返回 data。服務端文件一旦修改,服務端與客戶端的 ETag
值不等,並且狀態值會變為200,同時返回 data。
- (void)downloadFile
{
/*
1.NSURLRequestUseProtocolCachePolicy NSURLRequest 默認的cache policy,使用Protocol協議定義。
2.NSURLRequestReloadIgnoringCacheData 忽略緩存直接從原始地址下載。
3.NSURLRequestReturnCacheDataDontLoad 只使用cache數據,如果不存在cache,請求失敗;用於沒有建立網絡連接離線模式
4.NSURLRequestReturnCacheDataElseLoad 只有在cache中不存在data時才從原始地址下載。
5.NSURLRequestReloadIgnoringLocalAndRemoteCacheData 忽略本地和遠程的緩存數據,直接從原始地址下載,與NSURLRequestReloadIgnoringCacheData類似。
6.NSURLRequestReloadRevalidatingCacheData :驗證本地數據與遠程數據是否相同,如果不同則下載遠程數據,否則使用本地數據
*/
NSString *fileDownLoadPath = @"https://s3.cn-north-1.amazonaws.com.cn/zplantest.s3.seed.meme2c.com/area/area.json";
NSString *lastModified = [NSUserDefaults.standardUserDefaults stringForKey:@"Last-Modified"] ?: @"";
NSString *lastModifiedeTag = [NSUserDefaults.standardUserDefaults stringForKey:@"Etag"] ?: @"";
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:fileDownLoadPath]];
// request.cachePolicy = NSURLRequestUseProtocolCachePolicy;
// 服務器做對比, 不用重復下載
// [request setValue:lastModified forHTTPHeaderField:@"If-Modified-Since"]; // Last-Modified
[request setValue:lastModifiedeTag forHTTPHeaderField:@"If-None-Match"]; // ETag
[request setValue:@"no-cache" forHTTPHeaderField:@"Cache-Control"];
LMJWeakSelf(self);
NSLog(@"%@", request);
MBProgressHUD *hud = [MBProgressHUD showProgressToView:weakself.view Text:@"下載中"];
[[[LMJRequestManager sharedManager] downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
hud.progress = (downloadProgress.completedUnitCount) / (CGFloat)(downloadProgress.totalUnitCount);
NSLog(@"%lf", ((float)downloadProgress.completedUnitCount) / (downloadProgress.totalUnitCount));
} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
return [NSURL fileURLWithPath:[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:[fileDownLoadPath lastPathComponent]]];
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
[MBProgressHUD hideHUDForView:weakself.view animated:YES];
NSLog(@"%@", filePath);
NSLog(@"%@", response);
NSLog(@"%@", error);
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
[self.view makeToast:[NSString stringWithFormat:@"statuscode: %zd, \n200是下載成功, 304是不用下載", httpResponse.statusCode]];
NSString *lastModified = [httpResponse allHeaderFields][@"Last-Modified"];
NSString *lastModifiedeTag = [httpResponse allHeaderFields][@"Etag"];
if (lastModified && !error) {
[NSUserDefaults.standardUserDefaults setObject:lastModified forKey:@"Last-Modified"];
[NSUserDefaults.standardUserDefaults setObject:lastModifiedeTag forKey:@"Etag"];
}
NSLog(@"%@", lastModified);
}] resume];
}
文件下載的緩存策略