我正在使用以下代码从TfL下载一些数据。
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]
delegate:self delegateQueue:[NSOperationQueue mainQueue]];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://api.tfl.gov.uk/StopPoint/490012211N/Arrivals"]];
[[session dataTaskWithRequest:req
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (!error) {
NSLog(@"Loaded Succesfully");
}
NSCachedURLResponse *resp = [[NSURLCache sharedURLCache] cachedResponseForRequest:req];
if (resp) {
NSLog(@"Response in cache");
}
[[session dataTaskWithRequest:req
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (!error) {
NSLog(@"Loaded Sucessfully again");
}
}] resume];
}] resume];
响应的缓存控制标头字段为
public, must-revalidate, max-age=5, s-maxage=10
,这似乎意味着即使第二个请求在max-age给出的5秒钟内,服务器也将发送请求。如果我使用Charles编辑响应并删除必须重新验证的内容,那么上面的代码只会向服务器发送一次请求。HTTP / 1.1规范说
该缓存在过期后就不能再使用该条目来响应
后续请求,而无需先与原始服务器重新验证。
for
must-revalidate
,但是似乎iOS似乎忽略了“过时”部分?并以must-revalidate
表示忽略最大年龄。那么与将字段设置为根本不缓存有何不同。我已经检查过,并且请求/响应已添加到缓存中,所以must-revalidate
似乎使缓存变得肿,因为它将永远不会使用它,但仍将其添加到缓存中?那么服务器将
must-revalidate
与max-age
结合使用是不正确的,还是iOS处理must-revalidate
的方式不正确?有没有办法拦截响应,以便我可以删除
must-revalidate
? NSURLProtocol似乎很有用,但我只能看到如何修改请求,而不是响应。 最佳答案
如果使用NSURLProtocol,则可以发出一个新请求(一定要对其进行标记,以免再次修改它),然后在响应上,可以基于旧请求创建一个新的响应对象,并将修改后的响应发送给客户端。我不确定这是否足以解决您的问题。
但是,更好的解决方案(请阅读“实现起来更直接得多”)可能是将NSURLCache对象子类化,并使用您的自定义子类作为共享缓存(对于NSURLConnection和NSURLSession共享会话)或作为每个会话缓存(对于其他NSURLSession会话)。