AppCache: webové aplikace i bez připojení

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.
Seriál: Webdesignérův průvodce po HTML5 (21 dílů)
- Webdesignérův průvodce po HTML5 – díl nultý 25. 5. 2010
- Webdesignérův průvodce po HTML5 – nová sémantika 1. 6. 2010
- Webdesignérův průvodce po HTML5 – nová sémantika II 8. 6. 2010
- Webdesignérův průvodce po HTML5 – pohyblivé obrázky 15. 6. 2010
- Webdesignérův průvodce po HTML5 – používáme pohyblivé obrázky 22. 6. 2010
- Webdesignérův průvodce po HTML5 – taháme data od návštěvníka 29. 6. 2010
- HTML5 Audio: rádio ve vašich stránkách 13. 7. 2010
- Webdesignérův průvodce po HTML5: Microdata 20. 7. 2010
- AppCache: webové aplikace i bez připojení 27. 7. 2010
- Webdesignérův průvodce po HTML5: WebStorage 3. 8. 2010
- Webdesignérův průvodce po HTML5: Multithreading s WebWorkers 10. 8. 2010
- Webdesignérův průvodce po HTML5: Databáze v prohlížečích 17. 8. 2010
- Webdesignérův průvodce po HTML5: Shrnutí a rozhrnutí 24. 8. 2010
- HTML5: ukládáme si data k elementům 6. 12. 2010
- Webdesignérův průvodce po HTML5: Táhni a srůstej 5. 1. 2011
- HTML5: První krůčky s FileSystem API 15. 2. 2011
- Mobilizujeme web v HTML5 4. 4. 2011
- Single Page Apps a řešení problémů s historií 1. 6. 2011
- Page Visibility API: Kouká na mě vůbec někdo? 10. 8. 2011
- Práce se soubory v prohlížeči, díl 1 15. 8. 2011
- Práce se soubory v prohlížeči, díl 2 5. 9. 2011
Nálepky:
Ú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 nepodporují, 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 zavolatswapCache()
(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 metodyswapCache()
. -
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 metodaswapCache()
. 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.
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?
„Jak to vidí autor“, to nevím, ale mohu posloužit pohledem překladatele… :)
AppCache asi není nejvhodnější nástroj pro řešení offline DB aplikací. AppCache je dobrá na to, že do ní člověk může uložit např. rich text editor nebo „full-featured“ kalendář, tedy všechny ty nezbytné skripty a styly a ikonky, takže člověk, co potřebuje „online Word“ ho má k dispozici i offline, když si ho uloží jako „zástupce“ v Chrome nebo připraví v Mozilla Prism. Ovšem pokud má taková aplikace nějak pracovat s databází, je potřeba to řešit pomocí lokální databáze a synchronizovat změny, což už není úkol pro AppCache. Pro snazší představu: AppCache je pro ty soubory, co jsou u aplikace v „Program Files“, /usr/bin nebo zkrátka někde, kde je vlastní program a potřebné knihovny. Vlastní data jsou už někde jinde – a to „jinde“ bude potřeba řešit přes jiné metody, jako jsou WebStorages (ke kterým se na Zdrojáku dostaneme co nevidět).
Takže ve vašem případu budete mít v AppCache uloženy všechny JavaScripty a všechny ikonky a HTML s gridama, a skripty budou pracovat s lokálním úložištěm dat, které se bude synchronizovat se vzdálenou databází. Víc z AppCache asi nevymáčknete. :)
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?
Nevím co v nich funguje; informace o částečné podpoře jsem bral z Can I Use, odkaz je tam uvedený. Nemám ani FF3 ani Chrome 3, abych vyzkoušel co přesně umí a co ne, ale vzhledem k tomu, že se jedná o novou technologii, která se teprve rozšíří, tak bych řekl, že konkrétní míra podpory ve FF3 a Chrome 3 je irelevantní – dřív budou tyto verze zapomenuty než AppCache běžně používána.
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.
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 =)
Díky za upozornění, omlouvám se a opravuji.
„Tento kód bude každých 6é minut kontrolovat, …“ – 6é → 60
Jinak diky moc za serial, sleduju ;-)
Peace, dejaVu.
Opraveno, děkuji.
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.
Vzhledem k tomu, že AppCache je „working draft“, tak se obávám, že něco takového není nikde pevně specifikováno a nelze se na to spoléhat. Pravděpodobně tam je nějaký „rozumný limit“, ale těžko soudit, ostatně i Google vrací víc stránek s dotazy na velikost AppCache než autoritativních odpovědí.
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.
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!
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.networkmanager.disable, 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)