Почему браузер запрашивает кэшированный файл? - PullRequest
4 голосов
/ 28 февраля 2012

У меня есть эти директивы в моем htaccess :

# BEGIN Compress text files
<ifModule mod_deflate.c>
  <filesMatch "\.(css|js|x?html?|php)$">
    SetOutputFilter DEFLATE
  </filesMatch>
</ifModule>
# END Compress text files

# BEGIN Expire headers
<ifModule mod_expires.c>
  ExpiresActive On
  ExpiresDefault "access plus 1 seconds"
  ExpiresByType image/x-icon "access plus 86400 seconds"
  ExpiresByType image/jpeg "access plus 86400 seconds"
  ExpiresByType image/png "access plus 86400 seconds"
  ExpiresByType image/gif "access plus 86400 seconds"
  ExpiresByType application/x-shockwave-flash "access plus 86400 seconds"
  ExpiresByType text/css "access plus 86400 seconds"
  ExpiresByType text/javascript "access plus 86400 seconds"
  ExpiresByType application/javascript "access plus 86400 seconds"
  ExpiresByType application/x-javascript "access plus 86400 seconds"
  ExpiresByType text/html "access plus 600 seconds"
  ExpiresByType application/xhtml+xml "access plus 600 seconds"
</ifModule>
# END Expire headers

# BEGIN Cache-Control Headers
<ifModule mod_headers.c>
  <filesMatch "\.(ico|jpe?g|png|gif|swf)$">
    Header set Cache-Control "max-age=86400, public"
  </filesMatch>
  <filesMatch "\.(css)$">
    Header set Cache-Control "max-age=86400, public"
  </filesMatch>
  <filesMatch "\.(js)$">
    Header set Cache-Control "max-age=86400, private"
  </filesMatch>
  <filesMatch "\.(x?html?|php)$">
    Header set Cache-Control "max-age=600, private, must-revalidate"
  </filesMatch>
</ifModule>
# END Cache-Control Headers

# BEGIN Turn ETags Off
<ifModule mod_headers.c>
  Header unset ETag
</ifModule>
FileETag None
# END Turn ETags Off

# BEGIN Remove Last-Modified Header
<ifModule mod_headers.c>
  Header unset Last-Modified
</ifModule>
# END Remove Last-Modified Header

(взято из здесь )

Я использую Chrome для тестированияи я заметил, что файлы CSS, которые должны кэшироваться, на самом деле не кэшируются:

enter image description here

Заголовок запроса для одного случайного файла CSS:

Accept:text/css,*/*;q=0.1
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:es-ES,es;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Cookie:sua_language=en; keep=0; user=0; PHPSESSID=hn5gt5nb1j4sfq1j6m40un3it6; language=es
Host:podo.com
If-Modified-Since:Tue, 01 Nov 2011 17:20:59 GMT
Referer:http://podo.com/sheet?id=48
User-Agent:Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.53 Safari/534.30

и ответ:

Cache-Control:max-age=86400, public
Connection:Keep-Alive
Date:Tue, 28 Feb 2012 17:50:04 GMT
Expires:Wed, 29 Feb 2012 17:50:04 GMT
Keep-Alive:timeout=5, max=99
Server:Apache/2.2.15 (Unix) DAV/2 PHP/5.2.10
Vary:Accept-Encoding

У меня также есть следующий фрагмент кода, который выполняется перед любым файлом JS:

// Set document header
header('Content-Type: text/javascript; charset=UTF-8');

$expires = ONE_DAY;
header("Pragma: public");
header("Cache-Control: maxage=".$expires);
header('Expires: ' . gmdate('D, d M Y H:i:s', time()+$expires) . ' GMT');

, и я заметил, что, если я прокомментируюэти строки и перезагрузите страницу (не нажимая F5, используя кнопки навигации), некоторые (не все) файлы Javascript имеют то же поведение, что и файлы CSS (вынуждены перезагрузить).

Что происходит?Почему файлы CSS никогда не кэшируются?И почему файлы JS иногда кэшируются, а иногда нет?

ОБНОВЛЕНИЕ : Я обнаружил, что если я прокомментирую строкуи соответствующий закрывающий тег, все работает как положено, CSS-файлы не запрашиваются (как это происходит с JS-файлами).Теперь возникает вопрос: почему?

ОБНОВЛЕНИЕ 2 : заголовок ответа при первом получении файлов CSS (ответ 200):

Accept-Ranges:bytes
Cache-Control:max-age=86400, public
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:1633
Content-Type:text/css
Date:Thu, 01 Mar 2012 16:01:53 GMT
Expires:Fri, 02 Mar 2012 16:01:53 GMT
Keep-Alive:timeout=5, max=99
Server:Apache/2.2.15 (Unix) DAV/2 PHP/5.2.10
Vary:Accept-Encoding

заголовок запроса идентичен.

1 Ответ

3 голосов
/ 28 февраля 2012

На самом деле они кэшируются .Здесь важно отметить следующую строку запроса:

If-Modified-Since: Tue, 01 Nov 2011 17:20:59 GMT

Chrome просит сервер отправить новую копию файла тогда и только тогда, когда был измененначиная с Tue, 01 Nov 2011 17:20:59 GMT.

Ожидаемый ответ здесь будет одним из двух: если файл был изменен, сервер должен вернуть новую версию в теле ответа с кодом ответа 200 OK.Если файл не был изменен, сервер должен дать ответ 304 Not Modified, а тело ответа будет пустым - если вы посмотрите на код ответа, показанный в консоли, вы увидите, что это именно то, что происходит.

Для получения дополнительной информации см. этот раздел и этот раздел RFC2616.

Сноска : что интересно, у меня естьранее не наблюдалось, и я не могу с готовностью объяснить, почему ресурсы private используются с перепроверкой сервера, а ресурсы public - нет.По крайней мере, я предполагаю, что это происходит на основании того факта, что ваши файлы JS используются прямо из кэша, а ваши файлы CSS - нет.

...