【问题标题】:Strange NSURLConnection caching behaviour奇怪的 NSURLConnection 缓存行为
【发布时间】:2013-07-27 08:07:41
【问题描述】:

我有一个简单的方法,它接受一个 url 并从服务器加载它:

- (void)loadURL:(NSString*)url
{
    NSMutableURLRequest* request = [[NSMutableURLRequest alloc] init];
    request.HTTPMethod = @"GET";
    request.URL = [NSURL URLWithString:url];

    NSHTTPURLResponse* response;
    [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
}

服务器返回一个 max-age 为 1 天的响应。

问题是当我重复运行这 3 行时,其中 2 行随机错过缓存并重新加载响应:

[self loadURL:@"http://192.168.0.105:8080/users/51bdbc73808897302f000001/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09RoyipmXgcENwfE6EV9yzvgp5VTSZww"];
[self loadURL:@"http://192.168.0.105:8080/users/51ee9d4e263d08fe04000003/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09RoyipmXgcENwfE6EV9yzvgp5VTSZww"];
[self loadURL:@"http://192.168.0.105:8080/users/51d17b81de38c60b20000006/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09RoyipmXgcENwfE6EV9yzvgp5VTSZww"];

如果我在每个请求的查询字符串中添加一些随机的唯一数据(&x、&y、&z),它可以解决问题:

[self loadURL:@"http://192.168.0.105:8080/users/51bdbc73808897302f000001/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09RoyipmXgcENwfE6EV9yzvgp5VTSZww&x"];
[self loadURL:@"http://192.168.0.105:8080/users/51ee9d4e263d08fe04000003/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09RoyipmXgcENwfE6EV9yzvgp5VTSZww&y"];
[self loadURL:@"http://192.168.0.105:8080/users/51d17b81de38c60b20000006/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09RoyipmXgcENwfE6EV9yzvgp5VTSZww&z"];

另外,如果我将查询字符串的长度减少到 80 个字符,它也可以解决问题:

[self loadURL:@"http://192.168.0.105:8080/users/51bdbc73808897302f000001/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09Royipm"];
[self loadURL:@"http://192.168.0.105:8080/users/51ee9d4e263d08fe04000003/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09Royipm"];
[self loadURL:@"http://192.168.0.105:8080/users/51d17b81de38c60b20000006/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09Royipm"];

发生了什么事? 这是iOS中的错误吗?我该如何解决?

P.S:我在一个空的应用程序中测试了这个,在 iOS 5 和 6 上都没有额外的东西。

【问题讨论】:

  • 如何验证URL加载系统是从缓存中读取还是访问远程服务器?请求中设置了哪些缓存控制标头?客户端是否使用缓存?请注意,缓存可能会忽略服务器指定的过期时间。
  • @CouchDeveloper 我运行 'tail -f server.log | grep avatar' 以在请求进入时实时查看请求。服务器将 Cache-Control 标头设置为 'max-age=86400' 的值。并且客户端设置了 NSURLCache。
  • 您需要检查请求中的缓存控制标头。如前所述,客户端可以忽略从服务器或代理设置的到期日期。缓存相当复杂:13 Caching in HTTP
  • 您可能还会在服务器日志中看到“缓存验证”,其状态代码通常为 304,没有实体主体。
  • @CouchDeveloper 请求中没有与缓存相关的标头。我知道缓存的复杂性,但我需要知道为什么 NSURLConnection 的行为会根据 url 发生变化。

标签: ios objective-c nsurlconnection nsurlrequest nsurlcache


【解决方案1】:

NSURLRequest 中设置缓存行为requestWithURL:cachePolicy:timeoutInterval:。试试:

- (void)loadURL:(NSString*)url
{
    NSURL *url = [NSURL URLWithString:url];
    NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy: NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10.0];

    NSHTTPURLResponse* response;
    [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
}

也可以将NSURLRequestReloadIgnoringLocalAndRemoteCacheData 用于cachePolicy

【讨论】:

  • 这会改变缓存策略,因为它会绕过它,但并不能解释为什么有时应该不使用缓存。
【解决方案2】:

您可能想改用 ASIHTTPRequest http://allseeing-i.com/ASIHTTPRequest/

【讨论】:

    猜你喜欢
    • 2019-10-16
    • 1970-01-01
    • 2012-03-17
    • 2019-07-19
    • 2011-03-29
    • 2013-01-08
    • 1970-01-01
    • 1970-01-01
    • 2014-07-10
    相关资源
    最近更新 更多