Должен ли HTTP 304 Not Modified-responses содержать заголовки cache-control?
-
22-09-2019 - |
Вопрос
Я пытался понять это и искал SO похожие вопросы, но у меня все еще нет 100% понимания того, как это должно работать.
Я получаю этот ответ на запрос ресурса изображения:
Response Headers
Server Apache-Coyote/1.1
Date Mon, 19 Oct 2009 09:04:04 GMT
Expires Mon, 19 Oct 2009 09:06:05 GMT
Cache-Control public, max-age=120
Etag image_a70703fb393a60b6da346c112715a0abd54a3236
Content-Disposition inline;filename="binary-216-420"
Content-Type image/jpg;charset=UTF-8
Content-Length 4719
Желаемое поведение заключается в том, что клиент должен кэшировать это в течение 120 секунд, затем снова запросить это с сервера.В течение 120 секунд ни один запрос на сервер не отправляется.
Затем, через 120 секунд, отправляется запрос и принимается ответ 304:
Response Headers
Server Apache-Coyote/1.1
Date Mon, 19 Oct 2009 09:06:13 GMT
Request Headers
Host localhost:8080
User-Agent Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3
Accept image/png,image/*;q=0.8,*/*;q=0.5
Accept-Language en-us,no;q=0.8,sq;q=0.7,en;q=0.5,sv;q=0.3,nn;q=0.2
Accept-Encoding gzip,deflate
Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive 300
Connection keep-alive
Referer http://localhost:8080/cms/site/0/en/home
Cookie JSESSIONID=768ABBE1A3BFABE3B535900233330650; versionsCssDisplayState=block; iceInfo=iceOn:false,activePortletKey:,icePagePanelX:1722,icePagePanelY:3
If-None-Match image_a70703fb393a60b6da346c112715a0abd54a3236
Пока что все хорошо.Но затем, при следующем запросе (через 120 секунд), я бы подумал, что ресурс должен быть кэширован на 120 новых секунд.С другой стороны, что я вижу в браузере (Firefox), так это то, что с этого момента он всегда запрашивает ресурс и получает 304-ответ.
Должен ли я прикрепить заголовки cache-control в 304-ответе?Из того, что я могу прочитать в спецификации, кажется, что настройки управления кэшем должны быть опущены, и что кэш должен автоматически кэшировать его в течение 120 новых секунд?
Решение
Теоретически вам не нужно отправлять Cache-Control для 304 - получатель должен просто продолжать использовать директивы кэша, которые он получил от исходного 200.Однако, как вы обнаружили, на практике, если вы не продолжаете отправлять Cache-Control, браузеры будут игнорировать директивы кэша, которые вы отправили изначально, и вернутся к своей собственной эвристике по умолчанию.
Таким образом, на практике вы должны включить тот же элемент управления кэшем с номером 304, что и с номером 200.Спецификация требует, чтобы вы отправляли его за 304, только если он отличается от того, что вы отправляли ранее (см. 10.3.5 304 Не Изменено) - но это, конечно, не запрещает вам повторять это, когда это одно и то же.
И конкретно ответить на ошибочные замечания из другого ответа (Структуры):
Ты делай хотите, чтобы промежуточные кэши кэшировали ответ (то есть обновляли свою запись в кэше для ресурса).Они будут соответствующим образом отвечать на запросы от клиентов с помощью 200 или 304, в зависимости от того, включил ли клиент условный заголовок типа If-Modified-Since.
120-секундный ttl будет быть обновлен с помощью 304 (таким образом, тот же клиент не должен делать другой запрос к тому же ресурсу в течение, по крайней мере, еще 120 секунд).И клиенты, при условии, что у них все еще есть кэшированный контент, будет продолжайте делать условные запросы к ресурсу, на которые вы можете продолжать отвечать с помощью 304.
Другие советы
RFC7232 обновляет RFC2616, чтобы сказать:
Сервер, генерирующий ответ 304, ДОЛЖЕН сгенерировать любое из следующих полей заголовка, которые были бы отправлены в 200 (OK) ответ на тот же запрос:Управление кэшем, расположение содержимого, дата, Этот параметр, срок действия и изменяться.
Если я правильно понимаю, то браузер фактически кэширует в течение 120 секунд, и ваш сервер отвечает 304 Not Modified на последующие запросы If-Modified-Since.Этот запрос "IMS" возникает, когда конечный пользователь обращается к тому же URL-адресу.В это время браузер может отправить запрос If-Modified-Since.Браузер хочет знать, не отображает ли он устаревший контент.Это кажется нормальным.
После получения этого запроса ваш сервер должен ответить 200 OK, 304 Not Modified (или 4XX, если необходимо).
Я не верю, что вам следует настраивать свой сервер на отправку заголовка Cache-Control с ответом 304 по двум причинам:
1.Вы не хотите, чтобы какие-либо промежуточные кэши кэшировали этот ответ 304 (есть вероятность, что они могли бы)
2.120-секундный TTL не будет обновлен ответом 304.Браузер сохранит объект в течение 120 секунд с момента ответа 200 OK.Через 120 секунд браузер следует отправьте запрос GET, а не If-Modified-Since, поэтому ваш сервер ответит байтами файла, а не просто ответом 304.
Обратите внимание, что браузер не будет запрашивать файл снова автоматически через 120 секунд, если только конечный пользователь специально не запросит его через загрузку страницы или прямой ввод URL-адреса в свою адресную строку (или если у вас нет пользовательского приложения, которое каким-то образом управляет этой функциональностью).
Отредактировал первый абзац, чтобы читать немного лучше (надеюсь)