Как правильно настроить кеширование для css / js static - PullRequest
1 голос
/ 24 июля 2011

для предотвращения проблемы, когда я обновляю медиа-файлы CSS / JS, и браузеры не запрашивают новую версию, потому что они кэшируют эти файлы, я использовал это решение: https://github.com/jaddison/django-cachebuster,, который добавляет? к CSS / JS имена файлов (заменяет /media/main.css на /media/main.css?20012931203128. Я предполагал, что это заставит браузеры перезагружать файл css при изменении метки времени (файл обновляется) и использовать локальную кэшированную версию в другом случае. Но что Я вижу в журналах Apache (и в firebug), что браузеры (по крайней мере, Firefox) запрашивают файлы CSS / JS для каждой перезагрузки страницы, даже после получения кода 304, см. Фрагмент из журналов:

XXX.255.115.60 - - [24/Jul/2011:04:17:25 -0700] "GET /media/main.css?333900240611 HTTP/1.1" 304 172 "" "Mozilla/5.0 (Windows NT 5.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1"
XXX.255.115.60 - - [24/Jul/2011:04:17:26 -0700] "GET /media/main.js?270101180511 HTTP/1.1" 304 173 "" "Mozilla/5.0 (Windows NT 5.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1"
XXX.255.115.60 - - [24/Jul/2011:04:17:34 -0700] "GET /media/main.css?333900240611 HTTP/1.1" 304 172 "" "Mozilla/5.0 (Windows NT 5.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1"
XXX.255.115.60 - - [24/Jul/2011:04:17:35 -0700] "GET /media/main.js?270101180511 HTTP/1.1" 304 173 "" "Mozilla/5.0 (Windows NT 5.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1"
XXX.255.115.60 - - [24/Jul/2011:04:17:44 -0700] "GET /media/main.css?333900240611 HTTP/1.1" 304 172 "" "Mozilla/5.0 (Windows NT 5.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1"
XXX.255.115.60 - - [24/Jul/2011:04:17:44 -0700] "GET /media/main.js?270101180511 HTTP/1.1" 304 173 "" "Mozilla/5.0 (Windows NT 5.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1"

Конечно, это замедляет мой сайт. Можно ли заставить браузеры обновлять файлы только при изменении метки времени после .css? ...? Спасибо!

Upd: Вот пример ответа и запроса:

Запрос

User-Agent  Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.2.18) Gecko/20110614 Firefox/3.6.18
Accept  text/css,*/*;q=0.1
Accept-Language en-gb,en;q=0.5
Accept-Encoding gzip,deflate
Accept-Charset  ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive  115
Referer 
DNT 1
Connection  keep-alive
If-Modified-Since   Fri, 24 Jun 2011 05:39:33 GMT
If-None-Match   "8ed02f1-a21-4a66ea04f2f40"

Ответ

Date    Sun, 24 Jul 2011 12:28:21 GMT
Server  Apache
Connection  Keep-Alive
Keep-Alive  timeout=2, max=99
Etag    "8ed02f1-a21-4a66ea04f2f40"

Начальный соответственно

Date    Sun, 24 Jul 2011 12:51:05 GMT
Server  Apache
Last-Modified   Fri, 24 Jun 2011 05:39:33 GMT
Etag    "8ed02f1-a21-4a66ea04f2f40"
Accept-Ranges   bytes
Content-Length  2593
Keep-Alive  timeout=2, max=99
Connection  Keep-Alive
Content-Type    text/css

Ответы [ 2 ]

5 голосов
/ 24 июля 2011

Вы должны использовать правильные HTTP-кэширование директивы, чтобы ответы никогда не истекали (через год):

Cache-Control: max-age=31536000
Expires: Sun, 24 Jul 2012 12:51:05 GMT

Вы можете сделать это в Apache с помощью mod_expires :

ExpiresByType text/css "now plus 1 year"
ExpiresByType text/javascript "now plus 1 year"
1 голос
/ 24 июля 2011


Я много играл с этим и обнаружил, что это, вероятно, вызвано ошибкой Apache . Это не проблема браузера - когда временная диаграмма находится в строке запроса, браузер не понимает строку запроса и должен по крайней мере спросить сервер, не изменилась ли она. Apache хорошо отвечает «304 Не изменено», но он всегда отправляет файл тоже!

Я провел много экспериментов, и единственное решение, которое работало, было поместить метку времени непосредственно в имя файла . В PHP я использую следующую функцию:

function safe_inline_url($file)
{

     $basename = basename($file);
     if (strstr($basename, '.'))
          return dirname($file) . "/" .
               preg_replace('/(\.[^\.]*)$/', '_ts_' . filemtime($file) . '\1',
                    $basename);
     else 
          return $file . '_ts_' . filemtime($file);

}

, который изменяет любой встроенный URL (css, js, images, ...) так, чтобы он добавлял метку времени, например. как js / forms.js => js / forms_ts_1278080148.js .

На сервере вы должны затем переписать измененные имена файлов обратно в настоящие имена, что достигается путем помещения этого в ваш файл .htaccess:

RewriteEngine On

RewriteCond %{REQUEST_URI}      ^(.*)_ts_[0-9]{9,}$
RewriteRule ^                   %1      [PT]

RewriteCond %{REQUEST_URI}      ^(.*)_ts_[0-9]{9,}\.(.*)$
RewriteRule ^                   %1.%2   [PT]

вы помещаете его в корневой каталог, и вы также должны поместить его в .htaccess каждого подкаталога при включенном RewriteEngine .

Единственная проблема была с библиотекой JavaScript, которая использует URL для включения других источников - вы не можете использовать этот трюк для включения их js-файлов.

...