Почему Apache отправляет 200 OK, в то время как последнее изменение соответствует If-Modified-Since?

10

Я пытаюсь иметь базовое поведение в отношении моей стратегии кэширования: файлы должны кэшироваться и каждый раз повторяться на сервере. Поэтому я бы хотел, чтобы Apache отправил 304 обратно.

Вот диалог, который происходит для каждого обновления браузера:

Status Code:200 OK

Request Headers

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip,deflate,sdch
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Cache-Control:max-age=0
Connection:keep-alive
Cookie: ...
Host:...
If-Modified-Since:Tue, 14 Oct 2014 15:10:37 GMT
If-None-Match:"1461-505636af08fcd-gzip"
User-Agent:Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36

Response Headers

Accept-Ranges:bytes
Cache-Control:No-cache
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:1412
Content-Type:text/html
Date:Tue, 14 Oct 2014 16:58:05 GMT
ETag:"1461-505636af08fcd-gzip"
Keep-Alive:timeout=5, max=99
Last-Modified:Tue, 14 Oct 2014 15:10:37 GMT
Server:Apache/2.4.6 (Ubuntu)
Vary:Accept-Encoding

(это из chrome devtools, с отключенным отключением кэша)

Вы можете видеть, что ответ содержит заголовок Cache-Control: No-cache и заголовок If -ified-Since соответствует Last-updated. ETag тоже совпадает.

Разве Apache не отправляет 304 в этом случае?

РЕДАКТИРОВАТЬ

Отключение ETag в apache с помощью

 Header  unset ETag

делает поведение кэширования более предсказуемым ...

zrz
источник
Я думаю Cache-Control:max-age=0отключен кеш, поэтому вы видите Cache-Control:No-cacheответ.
ThoriumBR
Я явно установил Cache-Control: No-cache в моей конфигурации apache, потому что из w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1 я понимаю, что это вызывает повторную проверку для каждого запроса. Означает ли повторная проверка повторную отправку файла? Я бы сказал, что следует использовать If-
Modified-Since,

Ответы:

8

Кажется, это старая ошибка , объясняющая, почему это Header unset ETagимеет значение.

Apache 2.4.0+ автоматически добавляет имя метода сжатия в ETag (как видно из заголовков) и предотвращает ответ 304.

Новейшие версии mod_deflate поддерживают DeflateAlterETag, который можно использовать для управления этим поведением:

DeflateAlterETag NoChange
Матиас Р. Ессен
источник
3
Это правильно, но Apache 2.4 не содержит эту опцию, только Apache 2.5. Однако лично я не нахожу ETag полезными, поскольку Apache основывает их на дате последнего изменения, а не на содержимом файла. Таким образом, отключение ETags возвращается к заголовку If-Modified-Since, который в любом случае основан на дате последнего изменения. Вы можете изменить ETag в Apache, чтобы он основывался на размере, последнем изменении и / или inode - с размером и последним изменением по умолчанию - но до тех пор, пока они не добавят опцию для вычисления ETag на основе контрольной суммы содержимого файла, его ограниченного использования ИМХО. Поэтому я их выключаю.
Барри Поллард
1
@BazzaDP Это имеет смысл. 2.5 также имеет DeflateAlterETag Removeвозможность сделать именно это
Матиас Р. Джессен
0

Этот запрос выделяется в запросе как немного странный:

Cache-Control:max-age=0

Вероятно, более важно, хотя, я заметил, что возвращаемое содержание - HTML. Это генерируется динамически? Apache МОЖЕТ отправить ответ 304, но если вы не используете статический контент, Apache не выполняет этот вызов, и это зависит от логики вашего приложения. Например, большинство php-приложений имеют ограниченную поддержку для таких вещей.

Кэш внешнего интерфейса может помочь, так как приложение для кэширования может проверять время модификации, etag и т. Д., Но только если и приложение, и заголовки запросов являются дружественными к кэшу. Например, приложение должно установить соответствующие заголовки, чтобы указать, что контент кешируется, а такие вещи, как заголовок Cache-control в вашем запросе, будут отрицать кеш. Ваши заголовки не выглядят дружественными к кешу.

mc0e
источник
Запрашиваемый файл является статическим html-файлом, для которого Apache правильно выбирает время модификации. (Последнее изменение: вторник, 14 октября 2014 г., 15:10:37 по Гринвичу). заголовок max-age = 0 находится в запросе, отправленном Chrome, когда я набираю URL и нажимаю Enter. Это из-за предыдущих ответов?
zrz
Я читал, что Chrome автоматически добавляет Cache-Control: max-age = 0 к запросу (за исключением первой загрузки Chrome, введите URL-адрес, нажмите ввод). Но это, похоже, не влияет на другие серверы (CDN отправляют 304 даже с max-age = 0 в запросе).
zrz
@zrz: ограничение промежуточного кэширования очень полезно при отладке, но в противном случае может ухудшить производительность. Проверьте контекст того, что вы читаете о том, что делает Chrome. С точки зрения того, что делает apache, это вполне настраиваемо. Cache-control - это инструкция для промежуточных кэшей, а не для исходного сервера. Тем не менее, Apache может выступать в качестве промежуточного кэша и может быть настроен на все виды вещей. Я думаю, что если вы возьмете свои инструкции по анти-кешированию, вы получите поведение, более похожее на то, что вы ожидаете от исходного сервера.
mc0e
0

Если у вас настроен Apache Cache-Control:No-cache, Apache никогда не отправит HTTP 304 Not modifiedклиенту.

Если вы хотите пересмотреть некоторые запросы, поместите их Cache-Control:No-cacheтолько на те страницы, где вам это нужно. Вам не нужно повторно проверять все ресурсы, и вы тратите пропускную способность, делая это.

ThoriumBR
источник
Я, кажется, смущен термином «переоценить». Для меня это значит проверить, если это 304. Я ошибаюсь?
zrz
Вы неправы. Revalidate - это отправить все данные снова клиенту и заставить его снова прочитать все, даже если они уже имеют ту же информацию. Вы в основном отключаете кеш на каждом клиенте.
ThoriumBR
Это многое объясняет. Последнее, что мне нужно объяснить, имея в виду, что Apache отправляет 304 для некоторых ресурсов (например, png), в то время как Cache-Control в ответе не устанавливает No-cache, а в запросе max-age = 0. Любая подсказка?
zrz 14.10.14
@ThoriumBR Если я правильно вас понял, оба ваших ответа здесь неверны; no-cache (в отличие от no-store) не означает «не кешировать» и может привести к 304, если содержимое не изменилось. Действительно, ФП ожидал этого, но не получил его из-за проблемы с этагом. must-revalidate относится к тому, как обрабатывается устаревшее содержимое, и не всегда отправляет «все данные снова».
Ник