NSCachedURLResponse忽略HTTPBody

时间:2015-07-23 09:06:47

标签: objective-c caching nsurlrequest nsurlcache

我使用此代码创建NSMutableURLRequest

NSString *urlString = @"http://192.168.1.111/api";
NSURL *url = [NSURL URLWithString:urlString];

NSString *postBody = [NSString stringWithFormat:@"param=%@", param];
NSData *postBodyData = [postBody dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
NSString *postBodyLength = [@( postBodyData.length ) stringValue];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];

request.URL = url;
request.HTTPMethod = @"POST";
request.HTTPBody = postBodyData;
request.cachePolicy = NSURLRequestUseProtocolCachePolicy;

[request setValue:postBodyLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];

和此代码发出请求:

NSCachedURLResponse *cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:request];

if (cachedResponse && cachedResponse.data.length > 0) {
    NSError *serializationError = nil;

    id cachedResponseData = [NSJSONSerialization JSONObjectWithData:cachedResponse.data options:0 error:&serializationError];

    if (!serializationError) {
        NSLog(@"WEB: %@:%@ cachedResponseData: %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), cachedResponseData);

        [self showTranslations:cachedResponseData forWords:queryStrings withCallback:completion];
    }
} else {
    AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

    requestOperation.responseSerializer = [AFJSONResponseSerializer serializer];

    [requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"WEB: %@:%@ responseObject: %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), responseObject);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"WEB: %@:%@ error: %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), error);
    }];

    [[NSOperationQueue mainQueue] addOperation:requestOperation];
}

如果我首先使用等于param的{​​{1}}变量运行它,则会通过"first"块并发出请求。在第二次运行时,它会遍历else块并从缓存中检索响应数据。但是如果我再次使用等于if的{​​{1}}变量运行它,它会再次通过param块并从缓存中检索与第一个请求相对应的值。我怎样才能使像它应该那样工作并意识到这是一个不同的请求而不是从缓存中获取它?

1 个答案:

答案 0 :(得分:1)

AFNetworking可能会做一些奇怪的事情;我只能告诉你如何使用原生API来处理它,所以在你的情况下这可能是完全正确的。

如果内存服务,操作系统通常不会从缓存中检索POST请求,因为它们不被视为幂等的。因此,如果您正在查看缓存,则可能发生在设备外部的某个位置,例如网络代理。

话虽如此,指定NSURLRequestReloadIgnoringCacheData应该阻止它使用缓存数据。或者,您可以通过编写自定义缓存处理回调并返回nil而不是|对象来阻止它存储在缓存中。

但真正的问题是你直接查询缓存而不是让操作系统处理缓存。缓存没有请求类型或POST主体的概念。它只是在查看URL。如果您确实想要出于某种原因缓存POST请求,则必须以某种一致的方式连接URL和正文数据,然后为该修改的URL创建新的请求对象,并在添加时使用连接的请求对象数据和从缓存中检索数据。