如果服務(wù)器端直接將圖片改變了,而url沒有變,怎么辦?
當(dāng)采用GET方法請(qǐng)求的報(bào)文中含有If-Modified-Since首部時(shí),服務(wù)器端允許請(qǐng)求訪問(wèn)資源,但因?yàn)橘Y源未Modified,服務(wù)器端直接返回304 Not Modified,表示服務(wù)器端資源未改變,可直接使用客戶端未過(guò)期的緩存。
由此,我們可以將請(qǐng)求圖片的最近修改時(shí)間保存在If-Modified-Since中,當(dāng)再次請(qǐng)求此圖片時(shí),若資源未改變,返回304,表示我們可以繼續(xù)使用緩存中的這張圖片;若資源改變了,我們需要再一次下載此圖片。
[imageView sd_setImageWithURL: url placeholderImage:nil options:SDWebImageRefreshCached];
設(shè)置 SDWebImageOptions 為 SDWebImageRefreshCached 即使圖片已經(jīng)緩存了,在加載時(shí),還是向服務(wù)器發(fā)請(qǐng)求驗(yàn)證其資源是否修改。
第一次下載圖片并且緩存時(shí),必須保存其最近修改時(shí)間,便于下次判斷是否需要重新下載:
SDWebImageDownloader *imageDownloader = [[SDWebImageManager sharedManager] imageDownloader];
//設(shè)置downloader 的頭部過(guò)濾器
imageDownloader.headersFilter = ^NSDictionary *(NSURL *url, NSDictionary *headers) {
NSFileManager *fm = [[NSFileManager alloc] init];
NSString *imgKey = [[SDWebImageManager sharedManager] cacheKeyForURL:url];
NSString *imgPath = [[SDWebImageManager sharedManager].imageCache defaultCachePathForKey:imgKey];
//fileAttr 為圖片緩存時(shí)的一些信息
NSDictionary *fileAttr = [fm attributesOfItemAtPath:imgPath error:nil];
NSMutableDictionary *mutableHeaders = [headers mutableCopy];
NSDate *lastModifiedDate = nil;
if (fileAttr.count > 0) {
//若fileAttr不為空,取出最近修改時(shí)間
lastModifiedDate = (NSDate *)fileAttr[NSFileModificationDate];
}
//將時(shí)間格式化
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
formatter.dateFormat = @"EEE, dd MM yyyy HH:mm:ss z";
NSString *lastModifiedStr = [formatter stringFromDate:lastModifiedDate];
lastModifiedStr = lastModifiedStr.length > 0 ? lastModifiedStr : @"";
//存入首部
[mutableHeaders setValue:lastModifiedStr forKey:@"If-Modified-Since"];
return mutableHeaders;
};
這樣,發(fā)出的http請(qǐng)求將帶有If-Modified-Since首部,如圖:

第二次請(qǐng)求圖片時(shí)If-Modified-Since記錄最近更改時(shí)間
返回的響應(yīng)狀態(tài)碼為304,表示可以用客戶端緩存的圖片,資源并未修改,如圖:

返回碼為304,并且沒有請(qǐng)求頭