如何防止EVURLCache使用Cache-Control标头缓存请求?

时间:2016-08-18 14:20:06

标签: ios swift caching cache-control

我使用EVURLCache并且即使定义了cache-control和Pragma标头,也会缓存POST请求响应:

Headers: [
  Access-Control-Allow-Headers : Content-Type, Accept, X-Requested-With, remember-me, x-auth-token
  Content-Type : application/json;charset=UTF-8
  Access-Control-Max-Age : 3600
  Cache-Control : no-cache, no-store, max-age=0, must-revalidate
  Server : nginx/1.9.15
  Connection : keep-alive
  Transfer-Encoding : Identity
  X-XSS-Protection : 1; mode=block
  X-Content-Type-Options : nosniff
  Expires : 0
  X-Application-Context : application:dev,docker:8080
  Pragma : no-cache
  Access-Control-Allow-Methods : POST, GET, OPTIONS, DELETE, PUT
  Date : Thu, 18 Aug 2016 13:57:15 GMT
  Access-Control-Allow-Origin : *
  Access-Control-Allow-Credentials : true
]

如何强制EVURLCache不缓存此类请求?

我使用以下代码初始化我的app委托中的缓存:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    // configuring cache
    EVURLCache.LOGGING = true // We want to see all caching actions
    EVURLCache.activate()

    return true
}

请注意,我知道过滤器,但我想知道我们是否可以告诉它遵循响应头建议的缓存行为

1 个答案:

答案 0 :(得分:1)

我已经创建了一个更新(尚未推送到GitHub),并希望得到您的输入。解决此问题的代码是:

    var shouldSkipCache: String? = nil

    // check if caching is allowed according to the request
    if request.cachePolicy == NSURLRequestCachePolicy.ReloadIgnoringCacheData {
        shouldSkipCache = "request cache policy"
    }

    // check if caching is allowed according to the response Cache-Control or Pragma header
    if let httpResponse = cachedResponse.response as? NSHTTPURLResponse {
        if let cacheControl = httpResponse.allHeaderFields["Cache-Control"] as? String {
            if cacheControl.lowercaseString.containsString("no-cache")  || cacheControl.lowercaseString.containsString("no-store") {
                shouldSkipCache = "response cache control"
            }
        }

        if let cacheControl = httpResponse.allHeaderFields["Pragma"] as? String {
            if cacheControl.lowercaseString.containsString("no-cache") {
                shouldSkipCache = "response pragma"
            }
        }
    }

    if shouldSkipCache != nil {
        // If the file is in the PreCache folder, then we do want to save a copy in case we are without internet connection
        let storagePath = EVURLCache.storagePathForRequest(request, rootPath: EVURLCache._preCacheDirectory) ?? ""
        if !NSFileManager.defaultManager().fileExistsAtPath(storagePath) {
            EVURLCache.debugLog("CACHE not storing file, it's not allowed by the \(shouldSkipCache) : \(request.URL)")
            return
        }
        EVURLCache.debugLog("CACHE file in PreCache folder, overriding \(shouldSkipCache) : \(request.URL)")
    }

简而言之,这意味着:

  • 如果创建请求时指示缓存数据应该被签名,那么响应将不会写入缓存
  • 如果响应具有包含no-cache或no-store的Cache-Control标头,则响应将不会写入缓存
  • 如果响应的Pragma标头包含no-cache,则响应将不会写入缓存
  • 如果文件已在缓存中,则以上所有内容都将被忽略。 (至少应该更新)