Ответ на HTTP_IF_MODIFIED_SINCE и HTTP_IF_NONE_MATCH в PHP

Мне сделали кэшируемый динамический контент в PHP 5.1.0 +. Я уже отправляю корректные заголовки (включая Измененный в последний раз и Завершающий тег) клиентам.

Я теперь хочу, чтобы мой сценарий смог ответить $_SERVER['HTTP_IF_MODIFIED_SINCE'] и $_SERVER['HTTP_IF_NONE_MATCH'] когда существующий. Когда соответствия условий, я хочу ответить на a HTTP 304 "Not Modified" клиентам.

Каковы корректные условия? Когда точно я выпускаю 304 вместо целого содержания?

Принятый рассматриваемый ответ, Как знать, когда отправить 304 Не Измененный ответ, кажется, выпускает это правильно, но у меня есть трудные времена для портирования того кода на PHP 5.

Спасибо!

11
задан Community 23 May 2017 в 12:06
поделиться

5 ответов

[

]Я всегда использовал:[

] [
function caching_headers ($file, $timestamp) {
    $gmt_mtime = gmdate('r', $timestamp);
    header('ETag: "'.md5($timestamp.$file).'"');
    header('Last-Modified: '.$gmt_mtime);
    header('Cache-Control: public');

    if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) || isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
        if ($_SERVER['HTTP_IF_MODIFIED_SINCE'] == $gmt_mtime || str_replace('"', '', stripslashes($_SERVER['HTTP_IF_NONE_MATCH'])) == md5($timestamp.$file)) {
            header('HTTP/1.1 304 Not Modified');
            exit();
        }
    }
}
] [

]Не помню, писал ли я его или получал откуда-то еще...[

] [

]Обычно я использую его в верхней части файла таким образом:[

] [
caching_headers ($_SERVER['SCRIPT_FILENAME'], filemtime($_SERVER['SCRIPT_FILENAME']));
]
31
ответ дан 3 December 2019 в 02:20
поделиться

Ответ, на который вы ссылаетесь, кажется, содержит все, что вам нужно. Подводя итог:

  • сгенерируйте свои собственные заголовки ETag и Last-Modified, как если бы вы посылали все тело
  • посмотрите на заголовок If-Modified-Since, который прислал клиент, если ваш собственный последний-modified старше или тот же самый заголовок 304
  • посмотрите на заголовок If-None-Match клиента, если он совпадает с вашим собственным ETag, отправьте 304
  • если вы достигли этого места, заголовки не совпали, отправьте полное тело и новые ETag/Last-Modified заголовки
3
ответ дан 3 December 2019 в 02:20
поделиться

Вот фрагмент моей функции render_file().

$last_modified = filemtime($filename);
if ($last_modified === false) {
  throw new Exception('Modify date unknown');
}
if (array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER)) {
  $if_modified_since = strtotime(preg_replace('/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE']));
  if ($if_modified_since >= $last_modified) { // Is the Cached version the most recent?
    header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');
    exit();
  }
}
header('Last-Modified: '.date('r', $last_modified)); // tz should be GMT according to specs but also works with other tzs

// other headers and contents go here  
1
ответ дан 3 December 2019 в 02:20
поделиться

Если клиент совершил условный GET-запрос и доступ разрешено, но документ не был модифицированный, сервер ДОЛЖЕН ответить с этим кодом статуса. 304-й ответ НЕ ДОЛЖЕН содержать тело сообщения, а значит, всегда завершённый первой пустой строкой после полей заголовка.

From - http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5

Итак, если вы посылаете 304, не посылайте тело.

0
ответ дан 3 December 2019 в 02:20
поделиться
[

] Почему? [

] [

] Проведя много исследований на эту тему, я обнаружил, что условные запросы действительно замедляют работу сайта. Существуют определенные сценарии, где это не так, но, в целом, сопоставление с общими шаблонами использования приводит к более низкой пропускной способности и менее эффективному кэшированию.[

] [

]C.[

].
-3
ответ дан 3 December 2019 в 02:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: