Přejít k navigační liště

Zdroják » Webdesign » AppCache: webové aplikace i bez připojení

AppCache: webové aplikace i bez připojení

Články Webdesign

V dalším pokračování webdesignérova průvodce po technologiích z rodiny HTML5 si představíme nástroj, který umožňuje, podobně jako třeba Google Gears, provozovat webové aplikace i tehdy, když není uživatel online. To se – zejména ve spojení s mobilními zařízeními – opět ukazuje jako aktuální problém.

Úvod

Webové aplikace se stávají stále populárnějšími a mnoho z nás je používá téměř neustále. Nebylo by skvělé, kdyby fungovaly i offline? Až donedávna neexistoval jednoduchý způsob, jak toho dosáhnout, i když byly k dispozici proprietární řešení (Google Gears). S představením W3C HTML5 application cache nyní můžete spouštět webové aplikace offline stejně jako online. Ukažme si jak…

Proč by měla vaše aplikace fungovat offline?

Webové aplikace jsou den ode dne komplexnější a mají víc schopností. Existuje mnoho příkladů webových aplikací, co se svými schopnostmi vyrovnají desktopovým (Google Docs, Picasa apod.) Jejich hlavní nevýhodou je, že nefungují bez připojení na internet.

Právě tuto obtíž má řešit nové úložiště, představené v HTML5. Situaci s nedostupným připojením řeší určením způsobu, jak v takovém případě uložit potřebná data do lokální cache tak, aby je měl prohlížeč stále k dispozici. Těmi daty může být HTML, CSS, JavaScript nebo jakékoli jiné soubory, které webová aplikace potřebuje k běhu.

Dostupnost aplikační cache v prohlížečích:

  • IE: Verze 6, 7 i 8 nepodpo­rují, u verze 9 není zatím známo
  • Firefox: Ve verzi 3.0 částečně, od verze 3.5 podporuje
  • Safari: Od verze 4 podporuje
  • Chrome: Od verze 4 podporuje, ve verzi 3 částečně
  • Opera: Podporuje od verze 10.6

(informace pochází z webu Can I use…)

Ukládání souborů do aplikační cache pro offline použití

HTML5 specifikuje nástroj pro offline běh webových aplikací, který se nazývá aplikační cache, krátce označovaná AppCache. Soubory uložené v AppCache jsou dostupné z aplikace i v čase, kdy není připojena k internetu. Soubory, které chcete do AppCache uložit, určíte pomocí manifestu.

Jak se AppCache liší od normální cache prohlížeče?

Je spousta rysů, v nichž se AppCache liší od normální cache webového prohlížeče. Především se liší určením: AppCache je určena speciálně pro webové aplikace, cache prohlížeče naopak ukládá obecně webové stránky a jejich obsah. Normální cache může ukládat veškerý obsah, zatímco AppCache ukládá pouze obsah, který je specifikován v manifestu. V neposlední řadě je normální cache nespolehlivá – nevíme, jaké stránky (a jaké prvky z těchto stránek) jsou v cache uloženy.

AppCache dává vývojářům možnost řídit ji programem, což přináší větší míru kontroly nad tím, jak se webové aplikace budou chovat ve stavu offline. K lepší ovladatelnosti přispívá i API, pomocí něhož může programátor zjistit stav cache a např. vynutit její obnovení. Navíc může jednu AppCache sdílet více stránek v rámci jedné webové aplikace.

Soubor manifest

Tento soubor je umístěn na serveru a určuje, jaké soubory mají být uloženy u uživatele v AppCache prohlížeče, aby byly dostupné, i když je prohlížeč offline. Ukažme si trochu podrobněji, jak manifest vypadá.

Svůj manifest si můžete pojmenovat jakkoli, ale je dobrým zvykem dát mu příponu .manifest. Každý manifest začíná textem CACHE MANIFEST, po němž následuje seznam souborů, které mají být uloženy v AppCache, aby byly dostupné offline. Do manifestu lze zapisovat komentáře na řádky, které začínají znakem #. Velmi jednoduchý manifest může vypadat třeba takto:

CACHE MANIFEST
#Zde muzete pouzit hlavicku CACHE:
style.css
script.js
index.htm 

Soubor s manifestem musí mít správný MIME typ, konkrétně text/cache-manifest. Lze to zařídit několika způsoby, např. důsledným dodržováním použití přípony .manifest pro tyto soubory a přidáním následujícího řádku do  .htaccess:

AddType text/cache-manifest .manifest 

Propojení HTML s manifestem

Když máme vytvořen manifest, který určuje, jaké soubory mají být uloženy do cache, musíme říct HTML stránce, aby AppCache použila. To zajistíme tak, že uvedeme atribut manifest v tagu <HTML> naší stránky. Kupříkladu:

<html manifest="demo.manifest"> 

Pokud vaše webová aplikace používá víc než jednu stránku, ujistěte se, že manifest je nalinkovaný ze všech stránek, jinak nebudou uloženy do AppCache a aplikace nebude fungovat tak, jak si přejete.

Přesnější řízení AppCache pomocí sekcí

Viděli jsme velmi jednoduchý příklad manifest souboru. Pomocí různých sekcí můžeme určit u každého souboru, zda a jak má být cachován.

Explicitní určení souborů k cachování

Pokud chcete explicitně určit soubory, které mají být cachovány, můžete použít sekci CACHE:. Sekce je uvozena řádkem s textem CACHE:. Předchozí příklad může být přepsán takto (bez změny funkce):

CACHE MANIFEST
CACHE:
style.css
script.js
index.htm 

Jediný rozdíl je v tom, že jsme explicitně řekli, které soubory mají být uloženy do AppCache. Můžete se podívat na ukázkovou stránku, která používá sekci  CACHE: .

Je důležité poznamenat, že v manifestu musí být uvedeny cesty k souborům relativně k umístění souboru s manifestem. V příkladech zde budeme předpokládat, že všechny soubory jsou ve stejném adresáři jako manifest. V manifestu můžete při určování souborů k cachování použít relativní i absolutní URL.

Pokud se manifest nezmění, budou soubory uvedené v části  CACHE: nahrávány z AppCache (nikoli ze serveru) i v případě, že jste online. Pokud prohlížeč najde aktualizovaný manifest, obnoví obsah cache podle informací v tomto aktualizovaném manifestu. AppCache tudíž není vhodná pro aplikace, kde se neustále mění obsah, jako jsou blogy apod. Může však být velmi užitečná v aplikacích, které nabízejí nějakou jednoduchou činnost a mohly by pracovat offline (například kalendář nebo to-do list).

Co když chci u nějakého souboru obejít AppCache a načítat ho přímo ze serveru?

Pokud má HTML stránka uvedený manifest, budou cachovány pouze soubory, které jsou v manifestu výslovně uvedeny, a budou, jak jsme si výše řekli, do stránky načítány právě z cache. Můžou nastat situace, kdy je toto chování nevhodné a kdy bychom rádi načítali soubor přímo ze serveru (např. nějaký dynamicky generovaný obsah).

V základní podobě platí, že má-li stránka manifest, pak je veškerý síťový provoz pro tuto stránku blokován, a soubory jsou buď načteny z AppCache, nebo načítání selže. Pokud v manifestu použijeme sekci s hlavičkou NETWORK:, můžeme určit výjimku z tohoto pravidla. Pomocí sekce NETWORK: deklarujeme soubory, které NEMAJÍ být cachovány, tedy které budou nahrávány ze serveru a nebudou ukládány do cache. Sekce NETWORK: neovlivňuje chování obecné cache v prohlížeči. Pokud by tedy soubor měl být podle hlaviček uložen v cache prohlížeče, bude v ní uložen (jako jakýkoli jiný soubor bez AppCache), i když je v sekci  NETWORK: uveden jako soubor k načtení ze serveru.

CACHE MANIFEST
CACHE:
style.css
script.js
index.htm
NETWORK:
style2.css 

V tomto příkladu bude soubor style2.css vždy načítán ze serveru a nebude cachován v AppCache (i když může být uložen jako jakýkoli jiný CSS soubor v cache prohlížeče). Pamatujte si, že pokud je ve vaší aplikaci mnoho souborů, které mají být načítány ze serveru, může být jejich vypisování do sekce NETWORK: nepohodlné, takže v takovém případě můžete použít hvězdičku (*). Pak budou všechny soubory, které nejsou v manifestu uvedeny, načítány ze serveru (pokud bude uživatel online).

Chování si můžete ověřit v příkladu se sekcí NETWORK: . Pokud budete offline a zkusíte reload stránky, zjistíte, že stránka se celá načte, ale styl pozadí zmizí. To je způsobeno právě tím, že pozadí je stylováno v souboru style2.css, který je v sekci NETWORK:, což znamená, že není uložen v AppCache a je načten ze serveru.

Záložní obsah

Sekce FALLBACK: slouží k určení záložního obsahu, který je předán stránce v případě, že stahování souboru selže (nebo soubor není načten celý):

CACHE MANIFEST
CACHE:
style.css
script.js
index.htm
NETWORK:
style2.css
FALLBACK:
main_image.jpg backup_image.jpg 

Záložní obsah je uložen do cache a použit pouze v případě, že hlavní soubor nelze načíst. Ve výše uvedeném příkladu je do AppCache uložen soubor backup_image.jpg, a pokud nelze načíst main_image.jpg, je místo něj použit právě backup_image.jpg. Můžete si zkusit příklad se záložním obsahem — pokud načtete ukázkovou stránku, odpojíte se od internetu a dáte znovunačtení stránky, pokusí se prohlížeč načíst obrázek, ale protože není online (a obrázek není cachován), tak stahování selže. Místo něj je pak nabídnut záložní soubor z AppCache. (Prohlížeč má při pokusu o načtení poměrně velký timeout, než sáhne k záložnímu souboru, buďte proto při zkoušení trpěliví).

Příklad toho, jak lze určit náhradní obsah pro víc souborů, naleznete v příkladu s náhradním řešením pro více obrázků.

Použití AppCache API a událostí

Jedna z nejpříjemnějších vlastností AppCache je, že vy, programátor, máte možnost ovlivnit chování cache. Máte přístup k událostem, které informují o stavu AppCache, a k funkcím pro asynchronní aktualizaci. Můžete použít např. window.applicationCache, abyste zjistili, jestli prohlížeč AppCache podporuje nebo ne. Pojďme se podívat na příklady řízení aplikační cache pomocí uživatelského programu.

Stavy

Pomocí vlastnosti window.applicationCache.status můžete zjistit stav AppCache. Obsahem je číselná hodnota, označující stav dle následujícího seznamu:

0  – uncached
Tato hodnota je vrácena v případě, že stránka není v AppCache (nemá přiřazen manifest). Stav uncached je rovněž v okamžiku, kdy je stránka otevřena poprvé a prohlížeč stahuje soubory do AppCache.
1  – idle
Stav je roven idle ve chvílích, kdy má prohlížeč v AppCache aktuální verzi souborů a nejsou k dispozici novější.
2  – checking
Během času, kdy prohlížeč kontroluje aktualizaci manifestu, je stav AppCache nastaven na  checking.
3  – downloading
Během stahování nového obsahu cache (v případě, že byl zjištěn nový manifest) je stav roven  downloading
4  – updateready
Když prohlížeč dokončí stahování nového obsahu cache, je připraven k použití. Dokud není poprvé použit, je status  updateready
5  – obsolete
V případě že nebyl soubor s manifestem nalezen, je stav obsolete a aplikační cache bude smazána. Je důležité si uvědomit, že v případech, kdy download nového manifestu (nebo libovolného souboru v cache kromě těch s náhradním obsahem) selže, je to považováno za chybu, a je dál používán původní obsah AppCache.

Události

AppCache vyvolává při určitých stavech události, které můžeme programově zachytávat a reagovat na ně.

checking
událost je vyvolána ve chvíli, kdy se prohlížeč pokouší poprvé stáhnout manifest, nebo když hledá aktualizovanou verzi manifestu.
noupdate
Pokud nebyla nalezena aktualizovaná verze, je vyvolána událost  noupdate.
downloading
Tato událost je vyvolána ve chvíli, kdy prohlížeč načítá poprvé obsah aplikační cache nebo když aktualizuje obsah.
progress
Událost je vyvolána pro každý soubor, který byl stažen do AppCache.
cached
tato událost oznamuje, že všechny soubory byly staženy a aplikace je cachována.
updateready
Pokud prohlížeč úspěšně dokončí stahování aktualizovaného obsahu, vyvolá událost  updateready. Můžeme zavolat swapCache() (jak si ukážeme dále) a vynutit použití nové aktualizované cache.
obsolete
Tato událost je vyvolána v případě, že manifest není nalezen (404 error nebo 410 error).
error
Tato událost může být vyvolána z mnoha různých důvodů. Pokud prohlížeč nenalezne manifest, bude stahování obsahu do AppCache přerušeno a vyvolána událost error. Stejně tak bude vyvolána v případě, že manifest je v pořádku, ale některé soubory nelze načíst. Rovněž bude vyvolána v případě, že se manifest změní během aktualizace AppCache (pak prohlížeč před dalším pokusem o stažení bude nějakou dobu čekat), zkrátka ve všech případech, které signalizují zásadní chybu.

API aplikační cache má některé funkce, které stojí za zmínku:

  • window.applicationCache.update(): Voláním této metody můžeme vynutit stahování obsahu do AppCache, což má efekt podobný znovunačtení stránky. metoda zkontroluje, je-li dostupný aktualizovaný manifest, a pokud ano, stáhne kompletní obsah cache ze serveru. Důležité je vědět, že i když je vytvořena nová verze cache, stránka stále používá původní. Pokud chcete vynutit přepnutí na novou verzi, musíte tak učinit voláním metody  swapCache().

  • window.applicationCache.swapCache(): Tato metoda říká prohlížeči, aby použil nově vytvořenou cache, pokud je dostupná. Je důležité zmínit, že i v případě, že je k dispozici nový manifest, bude aplikace stále používat starou cache (z původního manifestu), dokud nebude zavolána metoda swapCache(). Po vyvolání swapCache() bude použita nová cache, tak jak je popsáno v aktualizovaném manifestu.

Většinou nemusíte používat funkci update(), protože o tyto činnosti se stará prohlížeč sám při reloadu stránky. Volání metody  swapCache() je pak nejčastěji spojeno s obsluhou události  onupdateready.

V následujícím příkladu si ukážeme použití těchto metod. Pokud změníte manifest a znovunačtete stránku, prohlížeč stáhne nové soubory a pak přepne na novou verzi cache (když je zavolána metoda  swapcache()):

<html manifest="demo.manifest">
<head>
<script type="text/javascript">
addEventListener('onupdateready', function(){
        window.applicationCache.swapCache();
}, false);
</script>
</head>
<body>
...
</body>
</html>

Pokud vaše stránka potřebuje být právě kvůli cache čas od času obnovena, a uživatel to neudělá sám, je možné nastavit časovač, který bude periodicky volat metodu update(). Ta zkontroluje manifest, a pokud je aktualizovaný, zavolá v obsluze události updateready metodu  swapcache(), čímž zajistí aktualizaci cache a přepnutí na tuto aktualizovanou­ verzi:

setInterval(
    function () { window.applicationCache.update(); },
    3600000);
// Hledá aktualizace manifestu každých 60 minut. Pokud je aktualizovaný, stáhne nový obsah cache tak, jak je definován v novém manifestu.
window.applicationCache.addEventListener('onupdateready',
 function(){ // když je cache aktualizována a připravena
    window.applicationCache.swapCache(); //přepneme na novou verzi
}, false);

Tento kód bude každých 60 minut kontrolovat, zda není na serveru k dispozici nový manifest. Pokud nalezne jinou verzi než tu, kterou má aktuálně k dispozici, vytvoří novou verzi cache a stáhne obsah podle nového manifestu. Jakmile se tak stane, je vyvolána událost updateready, která oznamuje, že aktualizovaná verze cache byla úspěšně stažena a je připravena k použití. Pak zavoláme metodu swapCache(), kterou vynutíme přepnutí ze staré verze na novou, právě staženou. Tímto způsobem zajistíme, že uživatelova cache bude stále aktuální.

Souhrn

W3C HTML5 application cache nabízí webovým vývojářům nové možnosti při psaní aplikací. webové aplikace mohou být nyní cachovány pro použití bez internetového připojení, což je přibližuje klasickým aplikacím, zejména ve spojení s lokálními úložišti WebStorage. Užitečnost offline webových aplikací možná neocení uživatel na běžném stolním PC v zaměstnání nebo doma, kde je internetové připojení dnes už rychlé, dostupné a neustále k dispozici, ale pro použití na mobilních zařízeních, často v terénu, kde signál není a ani nebude, je schopnost pracovat offline leckdy tou „killer feature“.

Tento článek je volným překladem anglického originálu vydaného na Dev.Opera. Autorem původního textu je Shwetank Dixit. Článek je zveřejněn s laskavým svolením Opera Software.

Komentáře

Subscribe
Upozornit na
guest
14 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
View all comments
Michal Holub

Ahoj, zrovna tohle jsem teď řešil u jedné db aplikace. Nic moc, pár gridů, formulářů…klient chtěl aby to fungovalo offline. Tahle featura HTML5 mě napřed nadchla ale teď přišla skepse :), nedovedu si moc představit, jak tu aplikaci přepsat…napadá mě jedině převést všechny odkazy na JS a hledat napřed v cache a až potom online. Drobný, ale ne nepřekonatelný, problém pak bude synchronizace dat…
Jak to vidí autor?

Michal Aichinger

To co nás taky zajímá se nedozvíme. Co v těch prohlížečích funguje a co, když píšeš, že mají částečnou podporu?

Ladislav Toral

Jen pro úplnost (hledal jsem to asi půl hodiny). Autor originálu z Opery se taktně vyhnul WinMobile, ale žádné překvapení, pro WM je dostupná pouze v10.0, a tam to zatím nefunguje.

BS-Harou

Máte chybu ve skriptu. Metodu addEventListener dáváte na objekt window, což je nesmysl. Podívejte se znovu na http://dev.opera.com/articles/view/offline-applications-html5-appcache/
S pozdravem, BS-Harou =)

dejaVu

„Tento kód bude každých 6é minut kontrolovat, …“ – 6é → 60
Jinak diky moc za serial, sleduju ;-)
Peace, dejaVu.

Hellish

Díky za zajímavý článek. Chtěl bych se zeptat jak je to s omezením na celkovou velikost cachovaných souborů. Je to nějak specifikované, nebo je to per browser (v nastavení Safari jsem to třeba nenašel).
Zajímá mě to proto, že dělám fotogalerii a offline prohlížení by i dávalo smysl, ale nevěřím, že přesvědčím browser aby cachoval všechny fotky, které mu nadiktuju.

VichJiri

Dobry den,

zajimalo by me co znamena stav prohlizece offline?

Ted jsem si tady s tim hral a prekvapilo me chovani metody navigator.onLine. At jsem pripojen k internetu nebo nejsem, stale mi to hazi true neboli online.

Kde muze byt chyba a co chapu spatne?

Dekuji za odpoved.

VichJiri

Tak jsem prisel na to, ze navigator.onLine spravne detekuje pripojeni v pripade zapnute funkce prohlizece „Pracovat offline“. Pokud ale odpojite sitovy kabel pise online (fce pracovat offline je vypnuta).

Opravdu nekdo netusi?

Diky!

Tom22

Tuší, ale ne ve 2 v noci ;)

Záleží na prostředí – myslím, že prohlížeči musí něco posílat info o připojení/odpojení.
Tohle dělá např. NetworkManager v Gnome – pokud se ovšem připojím jinak – např. k modemu přes pppd, tak o tom NetworkManager neví, nic firefoxu nepošle a ten si může myslet, že je/není připojen i když je to jinak.

Důležité je ovšem, že Firefox má v about:config volbu toolkit.networ­kmanager.disa­ble, která má patrně default true.
Teprve po změně na false to reaguje na on/off-line zprávy od NM.

snad to trochu pomůže
(pozor: testoval jsem to už před časem, teď to jen lovím z paměti)

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.