我正在使用最新的 RestKit 0.23.3
.您可能知道它适用于 AFNetworking 1.3.x
.
我有团队资源并从 API 服务器获取团队集合:我使用 RKObjectManager
及其-managedObjectRequestOperationWithRequest:managedObjectContext:success:failure:
RestKit
本身对我来说可以正常工作 - 我确实使用 GET /teams
获得团队请求 - 我在第一次请求时看到 200,在后续请求中看到 304。
但是,当我使用与 HEAD
完全相同的代码时我从未收到的请求 304
但总是 200
.
我对这一切进行了更多调查,发现在我的 iOS 应用程序收到对 GET /teams
的第一个响应后来自 Rails 服务器,此响应包含 Etag:
等后续请求iOS应用添加"If-None-Match:"[etag code...]"
这有助于 Rails 做出以 304 响应的决定。我注意到,当我使用 HEAD 请求 iOS 应用程序 时不 像 GET 请求一样混合“If-None-Match”。
我尝试设置除 NSURLRequestUseProtocolCachePolicy
之外的所有可能的缓存策略但这些政策都没有改变我。
如果请求 HEAD /teams
的 header 我手动混合If-None-Match:"[etag code...]"
使用从 HTTP 日志获得的 etag,即对 GET /teams
的响应我 开始为 HEAD
获得 304要求。
这让我觉得 NSURLConnection
的内部存在一些问题(错误?)阻止我的 iOS 应用程序发送 HEAD
与 If-None-Match:
标题存在且正确。
我将非常感谢任何能够对此有所了解的人。谢谢。
我猜这可能是 NSURLConnection 中的一个错误,如果有可能获得此 etag 并将其手动混合到我的 HEAD 请求中,我也将不胜感激。
相关话题:What response should If-Modified-Since HTTP Header return if request is HEAD?
@MikeS 的重要评论:
I did a quick test with straight NSURLConnection and it seems to work fine. I make a GET request, get back an ETag, and then make a HEAD request to the same URL and I can see the if-none-match header on the server side.
...
My original test was using iOS 8.0 in the simulator. I just re-tested with iOS 7.1 in the simulator and this time I did not get the if-none-match header with the HEAD request. Based on that, it does look like it's a bug in iOS 7.1, but it's fixed in iOS 8.0.
最佳答案
虽然我对此没有任何解释,但以下解决方法对我有用:
- (void)headTeamsWithHandler:(APIRequestArrayHandler)handler {
RKObjectManager *manager = ...;
NSDictionary *parameters = ...; // correct parameters with token and device ID
NSMutableURLRequest *teamsHEADRequest = [manager requestWithObject:nil method:RKRequestMethodHEAD path:TEAMS_PATH parameters:[self addDefaultParamsTo:nil]];
NSMutableURLRequest *teamsGETRequest = [manager requestWithObject:nil method:RKRequestMethodGET path:TEAMS_PATH parameters:[self addDefaultParamsTo:nil]];
NSCachedURLResponse *cachedTeamsResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:teamsGETRequest];
NSHTTPURLResponse *cachedTeamsHTTPResponse = (NSHTTPURLResponse *)cachedTeamsResponse.response;
NSString *cachedTeamsEtag = cachedTeamsHTTPResponse.allHeaderFields[@"Etag"];
[teamsHEADRequest setValue:cachedTeamsEtag forHTTPHeaderField:@"If-None-Match"];
AFHTTPRequestOperation *requestOperation = [manager.HTTPClient HTTPRequestOperationWithRequest:teamsHEADRequest success:^(AFHTTPRequestOperation *operation, id responseObject) {
// ...
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// ...
}];
[requestOperation start];
}
这当然需要两种情况都处理:当有缓存
GET /teams
响应以及当没有响应时。
关于ios - HTTP 缓存适用于 GET,但不适用于 HEAD(在 iOS 7.1 上永远不会为 HEAD 获得 304),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25878340/