Dajbych.net


Internet Explorer 9 a HTTP cache

, 4 minuty čtení

http logo

Poskytuje-li webová stránka datum poslední změny obsahu v HTTP hlavičce, může prohlížeč využít podmíněného HTTP požadavku. V případě žádosti o stránku, která už je uložena v cache prohlížeče, se s požadavkem pošle i její stáří. Server poté pošle obsah stránky jen v případě, došlo-li mezitím k její změně. V opačném případě zašle jen hlavičku, která značí, že ke změně nedošlo a ušetří se tak čas i síťový provoz.

Devátá verze Internet Exploreru přináší vylepšení tohoto chování. Nezbytnou součástí je však implementace ze strany dynamické webové aplikace, která by měla poskytovat alespoň čas poslední změny obsahu. Historicky má statická stránka datum změny souboru – tedy i jeho obsahu. U dynamické však toto datum s jejím obsahem nijak nesouvisí.

Nastavení z ASP.NET

Zjednodušeně řečeno, ASP.NET engine zpracovává serverový skript, který vygeneruje HTML kód. Ten je pak uložen v cache na straně serveru, aby pro mnoho stejných požadavků od různých klientů v krátkém čase stačilo zpracovat skript pouze jednou. HTML kód je pak také uložen do cache na straně klienta, aby se na několik stejných požadavků krátce po sobě stačilo dotazovat serveru jen jedenkrát. A po cestě se ještě může HTML stránka ukládat na proxy serveru. Ovlivnění, kde se stránka může a nemůže ukládat, se provádí přes metodu SetCacheability:

HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.ServerAndPrivate);

Téměř každý článek na webu obsahuje čas vydání, avšak málokterý už poskytuje tento čas v podobě čitelné pro caching – tedy v HTTP hlavičce odezvy. Přitom stačí jediný řádek kódu:

HttpContext.Current.Response.Cache.SetLastModified(article.Modified);

Metoda SetLastModified bere jako svůj jediný argument čas poslední změny dynamicky generované stránky typu DateTime. Ostatní systémy pak zařídí vše ostatní. Prohlížeč odesílá požadavek s hlavičkou If-Modified-Since a IIS spolu s ASP.NET na ní adekvátně reagují.

Expires / max-age

Server může definovat čas platnosti stránky zasláním hlavičky max-age, jejíž hodnota vyjadřuje počet sekund, po kterých je obsah stránky platný. Druhou možností je zaslání hlavičky Expires, jejíž hodnota vyjadřuje čas konce platnosti. Po jejím uplynutí se prohlížeč musí serveru dotazovat, jestli její platnost stále trvá. Použije k tomu hlavičku If-Modified-Since, ve které uvede čas posledního načtení stránky. Server na to může odpovědět HTTP/304 Not Modified v případě, že zjistí, že od té doby ke změně nedošlo. Prohlížeč pak použije stránku z cache a ušetří se přenos celé stránky.

ETag

ETag je hash obsahu stránky, který automaticky generuje IIS. Prohlížeč pak druhý dotaz na stejnou URL doprovází hlavičkou If-None-Match, ve které uvádí ETag získaný po prvním požadavku. Server poté může odpovědět HTTP/304 Not Modified.

Vary

Může se stát, že vrácený obsah závisí na nějaké HTTP hlavičce, typicky Accept-Language. Server může říct, že prohlížeč smí použít stránku z cache, jen když jsou hlavičky uvedené v hodnotě hlavičky Vary shodné. Internet Explorer 9 ignoruje hodnoty Accept-Encoding a User-Agent hlavičky Vary, protože obsah z cache je vždy dekomprimovaný a obsah stránky by neměl být závislý na použitém prohlížeči.

Redirect

Internet Explorer 9 nyní ukládá do cache automaticky stránky, které jen přesměrovávají. U přesměrování 301 Moved Permanently se IE 9 chová tak, že stránku uloží se do cache, pokud to není zakázáno (Cache-Control: no-cache). U přesměrování 302 Found a 307 Temporary Redirect se ukládá se do cache jen tehdy, je-li to povoleno (Cache-Control: max-age=120).

Zpět / vpřed

Upraveno je také chování při kliknutí na tlačítka zpět respektive vpřed. Internet Explorer 9 se chová podle normy RFC2616, která uvádí, že pokud uživatel klikne na již zmíněná tlačítka, prohlížeč by měl zobrazit stránku z cache i když její platnost již vypršela. V tomto případě se nebere zřetel ani na hodnotu must-revalidate v hlavičce cache-control. Nikdy se ale do cache neuloží stránka, která to zakazuje (Cache-Control: no-cache). Pokud však chcete stránku do cache ukládat jen pro použití v případě navigace zpět či vpřed, stačí použít Cache-Control: max-age=0.

Pokud server neřekne jinak

Mnoho serverů vůbec nespecifikuje, kdy platnost stránky končí. V této situaci se IE9 chová, na rozdíl od svých předchůdců, opět podle RFC2616. V případě, že server pošle alespoň hlavičku Last-Modified, je doba platnost stránky vypočtena takto:

max-age = (DownloadTime - LastModified) * 0.1

V případě, že se server ani neobtěžuje s posíláním hlavičky Last-Modified, je stránka považována za platnou po dobu dvanácti hodin nebo do zavření prohlížeče; podle toho, co nastane dřív.