2014-11-27 3 views
1

У меня есть прокси-скрипт на моем сайте, который уменьшает изображения (также хранит их в локальной папке кеша) и отправляет их пользователю вместе с Etag, заголовками кеширования и т. Д.Проблемы с кэшированием изображений - неправильные заголовки?

Однако, когда вы заходите на страницу, вы могут ясно видеть, как медленно загружаются изображения, даже когда вы закрываете вкладку и отправляетесь туда снова - ясно, что они должны быть в кеше (или, может быть, мое соединение отстойно, но я видел их перезагрузку даже при подключении 64 МБ/с)

Вы могут видеть изображения здесь, заголовок фотографии: http://www.ondrovo.com/

Я подозреваю, что я как-то посылаю неправильные заголовки, я не уверен в этом.

Вот моя функция доставки изображения (укороченный немного):

/** Send file to user */ 
public static function send($file) 
{ 
    // ETAG 
    $last_modified_time = filemtime($file); 
    $etag = md5_file($file); 

    header("Last-Modified: ".gmdate("D, d M Y H:i:s", $last_modified_time)." GMT"); 
    header("Etag: $etag"); 
    header('Expires: pageload + 168 hours'); 
    header('Cache-Control: public, max-age=604800, must-revalidate'); 

    // exit if not modified 
    if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $last_modified_time || 
     @trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag) { 
     header("HTTP/1.1 304 Not Modified"); 
     exit; 
    } 

    $mimetype = self::getMime($path); 
    if(in_array($mimetype, ['image/jpeg', 'image/png', 'image/pjpeg'])) { 
     // it's an image 
     if(isset($_GET['w']) || isset($_GET['h'])) { 
      // resize, save to cache folder 
      // $tmp_fname holds the path to the resized image 
      $file = $tmp_fname; 
     } 
    } 

    header('Content-Type: ' . $mimetype); 
    header('Content-Length: ' . filesize($file)); 

    readfile($file); 
    flush(); 
    exit; 
} 

Кроме того, здесь свалка заголовка, если он помогает

Запрос

GET /about/header.jpg?h=92&w=92 HTTP/1.1 
Host: www.ondrovo.com 
Connection: keep-alive 
Pragma: no-cache 
Cache-Control: no-cache 
Accept: image/webp,*/*;q=0.8 
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36 
Referer: http://www.ondrovo.com/ 
Accept-Encoding: gzip, deflate, sdch 
Accept-Language: cs,en-US;q=0.8,en;q=0.6 
Cookie: PHPSESSID=64e177be06a1b7bb665dd756151d014f 

Response

HTTP/1.1 200 OK 
Date: Thu, 27 Nov 2014 18:31:57 GMT 
Server: Apache 
Expires: pageload + 168 hours 
Cache-Control: public, max-age=604800, must-revalidate 
Last-Modified: Fri, 07 Nov 2014 14:39:09 GMT 
ETag: b38a22993d1fb1ee17905067340596e4 
Content-Length: 2268 
Content-Type: image/jpeg 
Via: 1.1 vhost.phx6.nearlyfreespeech.net:3128 (squid/2.7.STABLE7) 

Может кто-нибудь, пожалуйста, так любезны просмотреть мои заголовки, если они в порядке?

Возможно, это проблема, связанная с тем, что изображения получают свой размер с помощью параметров GET?

+1

подтвердите, что strtotime() фактически преобразует метку времени заголовка правильно. Никогда не зависеть от этого, делая «правильную вещь». Это хорошо, но это не непогрешимо и, безусловно, не всеведущее. –

ответ

0

Прежде всего, ваш заголовок Expires: pageload + 168 hours не соответствует правильному синтаксису. Это будет отметка времени.

5.3. Истекает

Поле заголовка «Истекает» дает дату/время, после которого ответ
считается устаревшим. См. Раздел 4.2 для дальнейшего обсуждения модели свежести.

Наличие Истекает поля не означает, что исходный
ресурс изменится или перестанет существовать, до или после этого
времени.

Значение Expires - это метка времени HTTP-даты, как определено в разделе 7.1.1.1 из [RFC7231].

Expires = HTTP-date 

Например

Expires: Thu, 01 Dec 1994 16:00:00 GMT 

Получатель кэш ДОЛЖЕН интерпретировать недопустимые форматы даты, особенно значение «0», как представление времени в прошлом (то есть, «уже
истек») ,

rfc 7234, section 5.3

Однако заголовок Cache-Control следует переопределить его для клиента.

Какой клиент вы используете для отслеживания? Похоже, что это было определенно предложено перезагрузить всю страницу, и от присутствия

Pragma: нет-кэша Cache-Control: нет кэша (с просьбой кальмара сервера не обслуживать кэшированное содержание)

И отсутствие заголовков, которые предполагают, что клиент уже имеет ресурс, кешированный (If-None-Match, If-Modified-Since).

Обратите внимание, что при посещении сайта в частном/инкогнито режиме, в зависимости от реализации функции, браузер может не кэшировать любой ресурс.

+0

Похоже, исправление тега expires очень сильно помогло. Кроме того, я обнаружил, что сценарий изменения размера изображения не использует сжатие png, поэтому он мог бы даже загружать время из локального кеша. Легко сделанный 1 МБ от изображения 64 КБ. – MightyPork

Смежные вопросы