繁体   English   中英

NSURLCache缓存不应缓存的随机响应

[英]NSURLCache caching random responses that should not be cached

我正在实现一个应用程序,它可以对我们也控制的rest-api进行大量的网络调用。 最近我们决定在服务器端引入缓存头,以节省一些宝贵的网络和服务器时间。 由于我们事先不知道数据有效期多长,我们不发送Cache-control: max-ageExpires标头,我们所做的就是发送Last-Modified标头和E-tag ,所以我们总是点击服务器但是大多数情况下304响应非常快。 一开始似乎一切正常,许多请求都被缓存了。 但是,由于缓存, 在应用程序上遇到一些随机数据错误

出于某种原因,我无法理解, 在某些时候,请求被本地缓存并且在没有命中服务器的情况下被用作“更新”数据,而实际上并非如此。 问题一直存在,直到一段时间过去。 然后一切都正常地再次进入服务器,就像它使用cache-control头一样,但没有它! 所以,我的问题是:


NSURLCache如何与NSURLConnection一起决定当原始请求没有附带Cache-control: max-age时,特定请求不需要联机Cache-control: max-ageExpires标头? 有谁经历过类似的影响? 如何在不删除整个缓存的情况下解决它?


更多背景信息:

  • 我正在使用AFNetworking ,但它依赖于NSURLConnection所以我认为它不会改变任何东西
  • 使用的缓存是默认的[NSURLCache sharedURLCache]实例
  • 这是一个GET请求,当我从缓存的响应中检查标头时,这就是我得到的:

    po [response allHeaderFields]

     "Access-Control-Allow-Headers" = "Content-Type"; "Access-Control-Allow-Methods" = "GET, POST, DELETE, PUT"; "Access-Control-Allow-Origin" = "*"; Connection = "keep-alive"; "Content-Encoding" = gzip; "Content-Length" = 522; "Content-Type" = "application/json"; Date = "Mon, 02 Sep 2013 08:00:38 GMT"; Etag = "\\"044ad6e73ccd45b37adbe1b766e6cd50c\\""; "Last-Modified" = "Sat, 31 Aug 2013 10:36:06 GMT"; Server = "nginx/1.2.1"; "Set-Cookie" = "JSESSIONID=893A59B6FEFA51566023C14E3B50EE1E; Path=/rest-api/; HttpOnly"; 
  • 我无法预测或重现错误何时发生,因此依赖于删除缓存的解决方案不是一种选择。

  • 我正在使用iOS5 +

NSURLCache如何与NSURLConnection一起决定特定请求何时不需要联机...

RFC 2616的第13.2节说:

由于源服务器并不总是提供明确的到期时间,因此HTTP缓存通常会分配启发式到期时间,采用使用其他标头值(例如Last-Modified时间)的算法来估计合理的到期时间。 HTTP / 1.1规范没有提供特定的算法,但确实对其结果施加了最坏情况的约束。 由于启发式到期时间可能会影响语义透明度,因此应谨慎使用,我们鼓励源服务器尽可能提供明确的到期时间。

因此,即使您没有为数据提供特定的生命周期,URL加载系统也可以确定缓存的数据“足够新鲜”。

为获得最佳结果,您应尝试在响应标头中提供特定的生命周期。 如果无法添加这样的标头,也许您可​​以改变请求。 if-modified-sincecache-control可以帮助您避免缓存数据。

根据声明“ 在某些时候请求被本地缓存并用作”更新“数据而不会命中服务器 ”我很确定您的请求是内存缓存的。

NSURLCache将数据缓存在内存中。 不在磁盘上 那么让我解释一下你可能会发生什么。

你启动了应用程序。 进行Web服务调用它从服务器获取数据再次进行调用,它从内存中获取响应,而不调用服务器并显示结果。

您离开应用程序一段时间或重新启动应用程序。 它会检查数据是否在内存中。 如果它不可用,则它再次调用服务器并重复相同的行为。

我建议你为自己编写自己的磁盘缓存,而不是依赖于NSURLConnection和NSUrlCache。 因为某些缓存政策还没有从Apple实施。

请确保您的NSURLRequest缓存策略设置为NSURLRequestReturnCacheDataElseLoad

如果您在AFHTTPClient.m中使用AFNetworking,则可以覆盖该方法

- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
                                  path:(NSString *)path
                            parameters:(NSDictionary *)parameters

用这个替换470行

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:15];

你实际做的是告诉加载缓存的请求,如果服务器没有更新..如果服务器更新,那么它将忽略缓存并从服务器下载内容

仅供参考:NSURLCache将数据存储在内存中。如果您想将数据存储在光盘中,可以在此处使用我的课程

https://github.com/shoeb01717/Disc-Cache-iOS

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM