【问题标题】:NSCachedURLResponse ignores HTTPBodyNSCachedURLResponse 忽略 HTTPBody
【发布时间】:2015-07-23 09:06:46
【问题描述】:

我正在使用此代码创建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];
}

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

【问题讨论】:

    标签: objective-c caching nsurlrequest nsurlcache


    【解决方案1】:

    AFNetworking 可能正在做一些奇怪的事情;我只能告诉您如何使用本机 API 来处理它,因此在您的情况下这可能完全正确,也可能不完全正确。

    如果内存提供服务,操作系统通常不会从缓存中检索 POST 请求,因为它们不被认为是幂等的。因此,如果您看到缓存,它可能发生在您设备之外的某个地方,例如网络代理。

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

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

    【讨论】:

    • 我明白了,很好的解释。另一种解决方案是使用GET 而不是POST。我确实想使用缓存,但不是针对不同的请求。
    • 当然,您当然也可以使用 GET 请求,前提是您的数据符合 GET 请求的长度限制并且服务器端在您的控制之下。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多