cache-control - CachedURLResponse 过期不起作用
问题描述
我试图为“ Cache-Control ”设置自定义标头以在客户端实现缓存(服务器端有“ Cache-Control: no-cache ”)。试图实现以下两个主要的事情。
- 一些端点的响应应该被缓存在内存中并且应该有一个过期时间(用户定义)
- 一旦过期时间结束,应用程序应该忽略缓存并从服务器获取数据。
我点击了这个链接,并能够实现第一个目标,但不知何故,即使在到期后应用程序仍在使用缓存并且没有触发任何 API 调用。不确定应用程序是否忽略了标题中设置的“最大年龄” 。如果我在这里遗漏了什么,请指导我。
以下是代码片段。
会话配置:
let sessionConfiguration: URLSessionConfiguration = URLSessionConfiguration.ephemeral
sessionConfiguration.requestCachePolicy = .returnCacheDataElseLoad
sessionConfiguration.urlCache = .shared
self.currentURLSession = URLSession(configuration: sessionConfiguration, delegate: self, delegateQueue: nil)
要求:
if let urlPath = URL(string: <WEB_API_END_POINT>){
var aRequest = URLRequest(url: urlPath, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 60)
aRequest.addValue("private", forHTTPHeaderField: "Cache-Control")
let aTask = self.currentURLSession.dataTask(with: aRequest)
aTask.resume()
}
缓存逻辑:
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, willCacheResponse proposedResponse: CachedURLResponse, completionHandler: @escaping (CachedURLResponse?) -> Void) {
if proposedResponse.response.url?.path.contains("/employees") == true {
let updatedResponse = proposedResponse.response(withExpirationDuration: 60)
completionHandler(updatedResponse)
} else {
completionHandler(proposedResponse)
}
}
CachedURLResponse 扩展:
extension CachedURLResponse {
func response(withExpirationDuration duration: Int) -> CachedURLResponse {
var cachedResponse = self
if let httpResponse = cachedResponse.response as? HTTPURLResponse, var headers = httpResponse.allHeaderFields as? [String : String], let url = httpResponse.url{
headers["Cache-Control"] = "max-age=\(duration)"
headers.removeValue(forKey: "Expires")
headers.removeValue(forKey: "s-maxage")
if let newResponse = HTTPURLResponse(url: url, statusCode: httpResponse.statusCode, httpVersion: "HTTP/1.1", headerFields: headers) {
cachedResponse = CachedURLResponse(response: newResponse, data: cachedResponse.data, userInfo: headers, storagePolicy: .allowedInMemoryOnly)
}
}
return cachedResponse
}
}
解决方案
能够自己修复它。如果帮助其他有需要的人,仍然分享答案。
在服务器响应中添加了“ Cache-Control ”响应头,我们有“ max-age:60 ”,这表明响应只能在 60 秒内有效。因此,直到 60 秒,应用程序将缓存该数据,并且在 60 秒后如果发出另一个请求,这将从服务器获取新数据。
这样,在客户端,除了定义缓存策略之外,不需要其他任何东西。您可以对整个 URL 会话执行此操作:
let sessionConfiguration: URLSessionConfiguration = URLSessionConfiguration.ephemeral
sessionConfiguration.requestCachePolicy = .useProtocolCachePolicy
sessionConfiguration.urlCache = .shared
self.currentURLSession = URLSession(configuration: sessionConfiguration, delegate: self, delegateQueue: nil)
或者可以根据特定要求进行。
if let urlPath = URL(string: <WEB_API_END_POINT>) {
var aRequest = URLRequest(url: urlPath, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 60)
let aTask = self.currentURLSession.dataTask(with: aRequest)
aTask.resume()
}
推荐阅读
- sql - 根据 2 列选择和过滤重复项
- ios - Swift:在计时器期间触发音效
- c# - RowStateChanged 事件中的索引超出范围,datagridview c#
- ios - Flurry 的正确桥接头是什么?
- java - 服务(java 文件)中的字段需要存储库类型的 bean
- php - PHP MySQL - 列出除 information_schema、mysql 之外的所有数据库
- c++ - 将 const char* 转换为 char 时出错
- php - 为什么 laravel 护照总是将 oauth_access_tokens 的 user_id 解析为整数?
- javascript - onmouseover 在选项中不起作用
- angular - 使用 Angular 5 的移动版本(www.example.com 的 www.m.example.com)的需求