Какие заголовки я хочу отправить вместе с ответом 304?

Когда я отправляю ответ 304. Как браузер интерпретирует другие заголовки, которые я отправляю вместе с 304?

E.g.

header("HTTP/1.1 304 Not Modified");
header("Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT");

Будет ли это гарантировать, что браузер не отправит еще один условный запрос GET (или какой-либо другой), пока не истечет время $ offset?

А как насчет других заголовков?

Должен ли я отправлять такие заголовки вместе с 304:

header('Content-Type: text/html');

Мне нужно отправить:

header("Last-Modified:" . $modified);
header('Etag: ' . $etag);

Чтобы убедиться, что браузер отправляет условный запрос GET в следующий раз, когда $ offset "закончится", или он просто сохраняет старые значения Last Modified и Etag?

Есть ли еще что-то, о чем я должен знать при отправке заголовка ответа 304?


person Willem    schedule 27.03.2009    source источник


Ответы (2)


Это сообщение в блоге очень помогло мне приручить зверя "условного получения".

Интересный отрывок (который частично противоречит ответу Бена) гласит:

Если нормальный ответ должен включать заголовок ETag, этот заголовок также должен быть включен в ответ 304.

Заголовки кэша (Expires, Cache-Control и / или Vary), если их значения могут отличаться от значений, отправленных в предыдущем ответе.

Это полностью соответствует RFC 2616 sec 10.3. .5.


Менее 200 запросов ...

HTTP/1.1 200 OK
Server: nginx/0.8.52
Date: Thu, 18 Nov 2010 16:04:38 GMT
Content-Type: image/png
Last-Modified: Thu, 15 Oct 2009 02:04:11 GMT
Expires: Thu, 31 Dec 2010 02:04:11 GMT
Cache-Control: max-age=315360000
Accept-Ranges: bytes
Content-Length: 6394
Via: 1.1 proxyIR.my.corporate.proxy.name:8080 (IronPort-WSA/6.3.3-015)
Connection: keep-alive
Proxy-Connection: keep-alive
X-Junk: xxxxxxxxxxxxxxxx

... И его оптимальный действительный аналог 304.

HTTP/1.1 304 Not Modified
Server: nginx/0.8.52
Date: Thu, 18 Nov 2010 16:10:35 GMT
Expires: Thu, 31 Dec 2011 16:10:35 GMT
Cache-Control: max-age=315360000
Via: 1.1 proxyIR.my.corporate.proxy.name:8080 (IronPort-WSA/6.3.3-015)
Connection: keep-alive
Proxy-Connection: keep-alive
X-Junk: xxxxxxxxxxx

Обратите внимание, что заголовок Expires составляет не более Current Date + One Year согласно RFC-2616 14.21.

person nulltoken    schedule 19.11.2010
comment
На самом деле я бы сказал, что ответ Бена частично верен, поскольку Expires и Etag необходимо указывать только в том случае, если они отличаются от оригинала (из выдержки из RFC выше). Конечно, как первоначально спросил Виллем, да, вы можете предоставить новый заголовок Expires, и он увеличит время кеширования клиента. - person mike nelson; 09.05.2013
comment
Обратите внимание, что дата Expires в HTTP 1.1 ограничена now + 1 year. Таким образом, 2037 год не считается действительным в этих обстоятельствах. w3.org/Protocols/rfc2616/rfc2616-sec14.html# sec14.21 «Серверы HTTP / 1.1 НЕ ДОЛЖНЫ отправлять даты истечения срока действия более чем на один год в будущем». - person Alexis Wilke; 27.03.2016
comment
@AlexisWilke Хороший улов! Хотели бы вы отредактировать этот ответ и исправить его? - person nulltoken; 27.03.2016

Заголовок Content-Type применяется только к ответам, которые содержат текст. Ответ 304 не содержит тело, поэтому этот заголовок не применяется. Точно так же вы не хотите отправлять Last-Modified или ETag, потому что ответ 304 означает, что документ не изменился (и поэтому ни у кого нет значений этих двух заголовков).

В качестве примера см. это сообщение в блоге Анны ван Кестерен, в котором исследуется WordPress 'http_modified. Обратите внимание, что он возвращает Last-Modified и ETag или ответ 304.

person Ben Blank    schedule 27.03.2009
comment
Не было w3.org/Protocols/rfc2616/rfc2616-sec10 .html # sec10.3.5 специально сказано, что если у оригинала был ETag, мы ДОЛЖНЫ включить его и в 304? - person Pacerier; 12.06.2013
comment
If-None-Match может содержать несколько ETag (поэтому он называется if-NONE-match. Браузер или кеширующий прокси-сервер могут кэшировать несколько версий документа, поэтому они отправляют ETag из ВСЕХ версий. Если вы этого не сделаете ответьте ETag, вызывающий не будет знать, какую версию использовать. - person Aaron Queenan; 21.08.2019