Заголовки HTTP ETag и If-None-Match не работают
У меня есть файл на моем веб-сервере, и я загружаю его в свое приложение каждый раз, когда к нему обращаюсь, потому что возможно, что содержимое файла может быть изменено. Но если оно будет изменено, я хотел бы загрузить это время только для того, чтобы можно было сохранить пропускную способность, и, к счастью, это то, что поля заголовка ETag и If-None-Match предназначены для.
- Когда я делаю запрос в первый раз, я получаю ETag из заголовков ответа HTTP
В последующих запросах на загрузку этого файла я бы прикрепил значение Etag для поля заголовка If-None-Match, чтобы в случае отсутствия изменений я получал бы код состояния HTTP-ответа 304 или же 200, если есть изменить в файле.
Замечания:
Когда я пытаюсь выполнить описанные выше шаги в Advanced REST Client Application в Chrome, он работает нормально, как и должно быть, но когда я пытаюсь сделать это в iOS, я всегда получаю код ответа 200, но он должен был дать мне 304 для последующих запросов.
Вот пример кода, который я использую
var request1 = NSMutableURLRequest(URL:NSURL(string: "http://10.12.1.101/Etag/ringtone1.mp3")!)
let Etagvalue="\"36170-52c1cc36d9b40\""
var session1 = NSURLSession.sharedSession()
request1.HTTPMethod = "GET"
var err: NSError?
request1.addValue(Etagvalue, forHTTPHeaderField: "If-None-Match")
var task = session1.dataTaskWithRequest(request1, completionHandler: {data, response, error -> Void in
print("response: \(response)")
})
Вот ответ
ответ: Необязательно ({URL: http://10.12.1.101/Etag/ringtone1.mp3 } {код состояния: 200, заголовки { "Accept-Ranges" = байты; Connection = "Keep-Alive"; "Content-Length" = 221552; "Content-Type" = "audio/mpeg"; Date = "Ср, 24 фев 2016 14:57:53 GMT"; Etag = "\"36170-52c1cc36d9b40\""; "Keep-Alive" = "timeout=5, max=100"; "Last-Modified" = " Пт, 19 фев 2016 10:15:33 GMT"; Server = "Apache/2.4.16 (Unix) PHP/5.5.29"; } })
Что я здесь не так делаю?
4 ответа
Я столкнулся с той же проблемой. Я обнаружил, что это из-за cachePolicy
, Вам нужно установить его следующим образом:
request.cachePolicy = .ReloadIgnoringLocalAndRemoteCacheData
И ты будешь в порядке
Соглашение об именах CachePolicy сбивает с толку и, тем не менее, оно не реализует некоторые из них...
Эта статья объясняет их хорошо. http://nshipster.com/nsurlcache/
Кроме того, если вы позволите политике кэширования использовать UseProtocolCachePolicy
тогда ваша NSURLSession получит код статуса 200
с ответом, сгенерированным из Cache.
Недавно был представлен .reloadRevalidatingCacheData, который звучит немного эффективнее, чем способ reloadIgnoringLocalAndRemoteCacheData прошлого.
Эта проблема связана с политикой кеширования useProtocolCachePolicy, returnCacheDataElseLoad или returnCacheDataDontLoad.
Вы можете использовать любую другую политику, кроме указанной выше. Желательно reloadIgnoringLocalAndRemoteCacheData.