Как настроить правильное кэширование в Apache?

Здравствуйте, уважаемые тостеровцы!

На разрабатываемом сайте обнаружил странную проблему с кэшированием изображений, css-, js-файлов.

На сервере использую LAMP:
- Debian GNU/Linux 7.5 (wheezy).
- Apache 2.2.22 (загруженные модули: alias, auth_basic, authn_file, authz_default, authz_groupfile, authz_host, authz_user, autoindex, cgid, deflate, dir, env, expires, fcgid, headers, mime, negotiation, reqtimeout, rewrite, setenvif, ssl, status, suexec, unique_id, xsendfile).
- PHP 5.4.4-14+deb7u11 (cgi-fcgi).

В директории с изображениями разместил файл .htaccess следующего содержания:
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresDefault "access plus 1 month"
    Header append Cache-Control "public"
</IfModule>

При первом запросе страницы серверу передаются следующие заголовки:
GET /images/some_image.png HTTP/1.1
Host:            example.com
User-Agent:      Mozilla/5.0 (Windows NT 6.3; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0
Accept:          image/png,image/*;q=0.8,*/*;q=0.5
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer:         https://example.com/
Connection:      keep-alive
Pragma:          no-cache
Cache-Control:   no-cache

И сервер отвечает следующим образом:
HTTP/1.1 200 OK
Date:            Tue, 01 Jul 2014 10:33:49 GMT
Server:          Apache/2.2.22 (Debian)
Last-Modified:   Mon, 09 Jun 2014 19:29:59 GMT
Etag:            "2016e1-50b-4fb6c3ca9a6b1"
Accept-Ranges:   bytes
Content-Length:  1291
Cache-Control:   max-age=2592000, public
Expires:         Thu, 31 Jul 2014 10:33:49 GMT
X-Frame-Options: sameorigin
Keep-Alive:      timeout=5, max=100
Connection:      Keep-Alive
Content-Type:    image/png

Как видно из них, сервер корректно устанавливает заголовки «Cache-Control» и «Expires».
При повторном запросе, когда изображение уже должно находиться в кэше, почему-то все равно отправляется запрос на сервер:
GET /images/some_image.png HTTP/1.1
Host:               example.com
User-Agent:         Mozilla/5.0 (Windows NT 6.3; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0
Accept:             image/png,image/*;q=0.8,*/*;q=0.5
Accept-Language:    ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding:    gzip, deflate
Referer:            https://example.com/
Connection:         keep-alive
If-Modified-Since:  Mon, 09 Jun 2014 19:29:59 GMT
If-None-Match:      "2016e1-50b-4fb6c3ca9a6b1"
Cache-Control:      max-age=0

И вот здесь меня смущает «Cache-Control: max-age=0». Так должно быть?

Ответ от сервера:
HTTP/1.1 304 Not Modified
Date:          Tue, 01 Jul 2014 10:48:10 GMT
Server:        Apache/2.2.22 (Debian)
Connection:    Keep-Alive
Keep-Alive:    timeout=5, max=98
Etag:          "2016e1-50b-4fb6c3ca9a6b1"
Expires:       Thu, 31 Jul 2014 10:48:10 GMT
Cache-Control: max-age=2592000, public

Соответственно, это каждый раз вызывает задержку при отображении картинок.
Подскажите, пожалуйста, в чем может быть проблема? В какую сторону копать?
Заранее спасибо!
  • Вопрос задан
  • 9683 просмотра
Пригласить эксперта
Ответы на вопрос 3
MaXComp
@MaXComp
интересуюсь frontend html+css+JS+php. Linux, C
Может так, как универсальное решение.

.htaccess

<ifModule mod_headers.c>
    #кэшировать html и htm файлы на один день
    <FilesMatch "\.(html|htm)$">
        Header set Cache-Control "max-age=43200"
    </FilesMatch>
    #кэшировать css, javascript и текстовые файлы на одну неделю
    <FilesMatch "\.(js|css|txt)$">
        Header set Cache-Control "max-age=604800"
    </FilesMatch>
    #кэшировать флэш и изображения на месяц
    <FilesMatch "\.(flv|swf|ico|gif|jpg|jpeg|png)$">
        Header set Cache-Control "max-age=2592000"
    </FilesMatch>
    #отключить кэширование
    <FilesMatch "\.(pl|php|cgi|spl|scgi|fcgi)$">
        Header unset Cache-Control
    </FilesMatch>
</IfModule>
<ifModule mod_expires.c>
    ExpiresActive On
    #по умолчанию кеш в 5 секунд
    ExpiresDefault "access plus 5 seconds"
    #кэшировать флэш и изображения на месяц
    ExpiresByType image/x-icon "access plus 2592000 seconds"
    ExpiresByType image/jpeg "access plus 2592000 seconds"
    ExpiresByType image/png "access plus 2592000 seconds"
    ExpiresByType image/gif "access plus 2592000 seconds"
    ExpiresByType application/x-shockwave-flash "access plus 2592000 seconds"
    #кэшировать css, javascript и текстовые файлы на одну неделю
    ExpiresByType text/css "access plus 604800 seconds"
    ExpiresByType text/javascript "access plus 604800 seconds"
    ExpiresByType application/javascript "access plus 604800 seconds"
    ExpiresByType application/x-javascript "access plus 604800 seconds"
    #кэшировать html и htm файлы на один день
    ExpiresByType text/html "access plus 43200 seconds"
    #кэшировать xml файлы на десять минут
    ExpiresByType application/xhtml+xml "access plus 600 seconds"
</ifModule>
Ответ написан
Комментировать
RicoX
@RicoX
Ушел на http://ru.stackoverflow.com/
Почему не хотите раздавать статику и кешировать через фронтенд на nginx?
Ответ написан
@neol
Если повторный запрос делается методом нажатия на F5, то это нормально. В таком случае браузер (как минимум chrome и ff ) проверяет, что данные актуальны. Если просто ходить по сайту, то контент будет браться из кеша без проверки.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы