【问题标题】:AFNetworking caching using ETag使用 ETag 的 AFNetworking 缓存
【发布时间】:2015-10-27 00:58:20
【问题描述】:

我在使用 AFNetworking 和 ETag 值实现缓存时遇到问题。我的服务器为每个请求返回 Cache-Control 和 ETag 标头值。但是,如果我再次请求同一资源,AFNetworking 将不会添加 ETag。我应该为收到的每个响应手动保存 etag 并将其附加到下一个请求吗?

在应用委托中我设置了缓存对象:

 NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:20 * 1024 * 1024 diskCapacity:20 * 1024 * 1024 diskPath:nil];
 [NSURLCache setSharedURLCache:URLCache];

另外,我使用的是 AFHTTPRequestSerializer 的默认缓存策略。

任何想法是什么问题?也许我不明白http缓存的想法。据我所知,它应该是透明的,我所要做的就是为每个响应附加 ETag 和 Cache-Control 标头。

编辑

响应的标头如下所示:

"Cache-Control" = "max-age=3600";
"Content-Encoding" = gzip;
"Content-Type" = "application/json; charset=utf-8";
Date = "Wed, 05 Aug 2015 07:52:33 GMT";
Etag = "W/f6c8a0f47deb7db0eeea3069061de9ab";
Expires = "Wed, 05 Aug 2015 08:52:30 GMT";
"Last-Modified" = "Wed, 05 Aug 2015 08:52:30 GMT";
Server = "cloudflare-nginx";
Vary = "Accept-Encoding";
"cf-ray" = "2110ec564bde0afc-WAW";
"x-cache-id" = "api_3447fddb8680ed5d082ae871e95214dc";
"x-powered-by" = "PHP/5.5.19";
"x-whom" = "www-stage02-b"

【问题讨论】:

  • 它应该默认工作,你确定你在两边都正确设置了所有标题吗?服务器端也需要附加这些标头。
  • 您可以使用“[[操作响应] allHeaderFields]”检查服务器响应
  • 两边是什么意思? AFNetworking 不应该为相应的请求路径自动附加带有最新 Etag 值的 If-None-Match 标头吗?我已附加响应标题(使用编辑)。你能看出有什么问题吗?
  • 看起来没问题,让我粘贴代码来确认请求是否从缓存中加载

标签: ios objective-c caching afnetworking nsurlcache


【解决方案1】:

要检查您的 AFHTTPRequestOperation 是否来自缓存,您可以使用以下代码:

- (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)request
                                                    success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
                                                    failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
{
    NSMutableURLRequest* mutableRequest = [request mutableCopy];
    BOOL __block responseFromCache = YES;

    AFHTTPRequestOperation* operation = [super HTTPRequestOperationWithRequest:mutableRequest
    success:^(AFHTTPRequestOperation *operation, id responseObject)
    {
        NSString* source = responseFromCache ? @"CACHE" : @"SERVER";
        NSLog(@"Request from %@", source);
        success(operation, responseObject);
    }
    failure:nil];

    [operation setCacheResponseBlock:
     ^NSCachedURLResponse *(NSURLConnection *connection, NSCachedURLResponse *cachedResponse) {
         responseFromCache = NO;
         return cachedResponse;
     }];

    return operation;
}

确保您在应用程序开始运行时也启用了 NSURLCache。

NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:5 * 1024 * 1024
                                                     diskCapacity:50 * 1024 * 1024
                                                         diskPath:nil];
[NSURLCache setSharedURLCache:URLCache];

【讨论】:

  • 我确定响应来自服务器,而不是缓存。我正在使用应用程序 Charles,我可以跟踪响应和请求的所有详细信息。问题是请求没有 If-None-Match 标头。
  • 是的,我在我的问题中附加了负责该问题的代码。
猜你喜欢
  • 1970-01-01
  • 2012-12-17
  • 2015-02-18
  • 2013-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-25
  • 1970-01-01
相关资源
最近更新 更多