Черновики
quittance.ru
документы
прочее
Авторские дневники
   / черновики
   / заметки о типографике
   / SEO FAQ для неспециалистов

Принудительное обновление привязанных CSS-файлов

Зна­ко­мая си­ту­а­ция: по­сле об­нов­ле­ния ста­ти­че­ских CSS-фай­лов, про­дол­жа­ют ис­поль­зо­вать­ся их ста­рые вер­сии из ке­ша (англ. cache) бра­у­зе­ра или proxy-сер­ве­ра, в ре­зуль­та­те че­го стра­ни­ца вы­гля­дит обез­об­ра­жен­ной. Этот же непри­ят­ный эф­фект по­рою на­блю­да­ет­ся и с дру­ги­ми ста­ти­че­ски­ми фай­ла­ми: с гра­фи­кой, с фай­ла­ми JavaScript и про­чими…

Боль­шин­ство веб-сер­ве­ров с на­строй­ка­ми по умол­ча­нию для ста­ти­че­ских фай­лов не от­да­ют за­го­лов­ки с ин­фор­ма­ци­ей о па­ра­мет­рах ке­ши­ро­ва­ния. Поэто­му бра­у­зе­ры ке­ши­ру­ют та­кие фай­лы по сво­е­му усмот­ре­нию в со­от­вет­ствии с соб­ствен­ны­ми на­строй­ками.

Осо­бен­но непро­сто бы­ва­ет за­ста­вить Internet Explorer об­но­вить при­вя­зан­ные фай­лы, да­же ес­ли мно­го­крат­но на­жи­мать на кноп­ку «Обно­вить» (англ. Refresh).

Конеч­но, мож­но на­стро­ить веб-сер­вер, чтобы он от­да­вал за­го­лов­ки на пол­ный за­прет ке­ши­ро­ва­ния опре­де­лен­ных ти­пов фай­лов, или уста­но­вить для них ми­ни­маль­ный пе­ри­од ак­ту­аль­но­сти ке­ша… Но есть спо­соб, поз­во­ля­ю­щий эф­фек­тив­но ис­поль­зо­вать ме­ха­низм ке­ши­ро­ва­ния, и в то же вре­мя га­ран­ти­ро­ван­но из­бе­жать отоб­ра­же­ния уста­рев­ших ко­пий из кеша.

Изящ­ное и по­чти уни­вер­саль­ное ре­ше­ние во­про­са пред­ло­же­но в за­мет­ке Web Hosting Talk  How do I force reload of updated CSS after site design changes.

Идея со­сто­ит в том, что к ссыл­ке на ста­ти­че­ский файл до­бав­ля­ет­ся фаль­ши­вый па­ра­метр, от­ра­жа­ю­щий вре­мя по­след­не­го из­ме­не­ния это­го ста­ти­че­ско­го файла.

Для сер­ве­ра фаль­ши­вый па­ра­метр ста­ти­че­ско­го фай­ла не име­ет ни­ка­ко­го зна­че­ния и бу­дет про­игно­ри­ро­ван. Но с точ­ки зре­ния кли­ен­та, по­сле из­ме­не­ния ста­ти­че­ско­го фай­ла из­ме­нит­ся и url, по­это­му бра­у­зер га­ран­ти­ро­ван­но его об­но­вит и бу­дет ис­поль­зо­вать ак­ту­аль­ную вер­сию.

И на­про­тив, ес­ли файл не из­ме­нял­ся, то ссыл­ка на него оста­нет­ся преж­ней, что даст кли­ен­ту воз­мож­ность ис­поль­зо­вать ко­пию из ке­ша в со­от­вет­ствии с его на­строй­ками.

Метод эф­фек­ти­вен, ес­ли ссы­ла­ю­щий­ся до­ку­мент ге­не­ри­ру­ет­ся ди­на­ми­че­ски. Для ста­ти­че­ских до­ку­мен­тов зна­че­ние фаль­ши­во­го па­ра­мет­ра при­шлось бы из­ме­нять вруч­ную.

Ниже при­ве­де­на про­стая ре­а­ли­за­ция это­го ре­ше­ния на php5 при­ме­ни­тель­но к таб­ли­цам сти­лей CSS.

Под­дер­жи­ва­ют­ся толь­ко от­но­си­тель­ные ссыл­ки, то есть ссыл­ки на ло­каль­ные фай­лы. Рабо­та с уда­лен­ны­ми фай­ла­ми по аб­со­лют­ным ссыл­кам не ре­а­ли­зо­ва­на по при­чине от­сут­ствия у ав­то­ра та­кой необ­хо­ди­мо­сти. Если к ука­зан­но­му фай­лу CSS невоз­мож­но об­ра­тить­ся как к ло­каль­но­му, то его url вы­во­дит­ся как есть, без до­бав­ле­ния па­ра­метра.

<?php
// sk_link_css: generates css link tag with fake version parameter,
// to enshure the actual version will be loaded
// $css: css filename; only local files are supported
// $media: optional media attribute; default: no media attribute
// $is_xhtml: make xhtml tag: default: make html tag
 
function sk_link_css($css, $media = '', $is_xhtml = false) {
 
// if the first character is "/" we need to add server's
// document root before local filename
$fn = (($css{0} === '/') ? $_SERVER['DOCUMENT_ROOT']. $css : $css);
if (is_file($fn)) {
list( , , , , , , , , , $lastmod) = stat($fn);
$ret = $css. '?v='. $lastmod;
 
// if css can't be accessed as local file, return as is
} else $ret = $css;
 
return '<link rel="stylesheet" type="text/css" href="'. $ret. '"'.
(($media) ? ' media="'. $media. '"' : '').
(($is_xhtml) ? ' /' : ''). '>'. "\n";
}
?>

комментировать 10/06/2010
Copyright 2009–2010 Sergey Kurakin