Подтвердить что ты не робот

Должны ли HTTP 304 Not Modified-response содержать заголовки управления кешем?

Я пытался понять это и искал 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-ответ.

Предполагаю ли я прикреплять заголовки управления кешем в 304-ответе? Из того, что я могу прочитать в спецификации, кажется, что параметры кеш-контроля должны быть опущены и что кэш должен кэшировать его на 120 новых секунд автоматически?

4b9b3361

Ответ 1

В теории вам не нужно отправлять Cache-Control для 304 - получатель должен просто продолжать использовать директивы кэша, полученные от оригинала 200. Однако, как вы нашли, на практике, если вы не отправляйте Cache-Control, браузеры будут игнорировать директивы кэша, которые вы отправили изначально, и верните их собственные эвристики по умолчанию.

Таким образом, на практике вы должны включить тот же Cache-Control с 304, что и с 200. Спецификация только требует, чтобы вы отправили его для 304, если он отличается от того, что вы отправили ранее (см. 10.3.5 304 Не изменено) - но это, конечно же, не запрещает вам повторять его, когда оно то же самое.

И чтобы ответить конкретно на неверные точки от другого ответа (Structure):

  • Вы хотите, чтобы промежуточные кэши кэшировали ответ (т.е. обновляли свою запись кэша для ресурса). Они будут отвечать соответствующим образом запросам клиентов с 200 или 304, в зависимости от того, включал ли клиент условный заголовок, например, If-Modified-Since.

  • 120-секундный ttl будет обновлен 304 (так что тот же клиент не должен делать другой запрос для того же ресурса, по крайней мере, еще на 120 секунд). И клиенты, пока они до сих пор хранят кешированный контент, будут продолжать делать условные запросы для ресурса, на которые вы можете продолжать отвечать с помощью 304.

Ответ 2

RFC7232 обновляет RFC2616, чтобы сказать:

Сервер, генерирующий ответ 304, ДОЛЖЕН создать любую из    следующие поля заголовка, которые были отправлены в 200 (OK)    ответ на тот же запрос: Cache-Control, Content-Location, Date,    ETag, Expires и Vary.

Ответ 3

Если я правильно понимаю, то браузер на самом деле кэширует 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-адрес в свою адресную строку (или если у вас нет настраиваемого приложения, которое контролирует эту функциональность как-то).

Отредактирован первый абзац, чтобы прочитать немного лучше (надеюсь)