Chtěl jsem dlouho omrknout lákavou část HTML5 specifikace, a to tvoření webové aplikace i pro offline režim. Jelikož je podpora na dobré cestě (Chrome 4.0, Firefox 3.5, IE 10), rozhodl jsem se místo nějaké minutkové stránky udělat rovnou něco užitečného – například offline stránku pro BOObook.cz, kde by byla omezená nabídka s možností vložit do košíku a synchronizací ihned po obnově spojení. K tomu ještě možnost zobrazit si poslední známý stav košíku a wishlistu. Jen takové srandičky.
Bohužel jsem ale narazil na nepříjemnou drobnost, díky které už nemám takovou
chuť si s offline verzí webové aplikace tolik hrát. Nejprve ale zběžně
vysvětlím, jak to celé funguje – do tagu html
se vloží atribut manifest
s
odkazem na soubor manifestu. Takový soubor může vypadat například takto:
CACHE MANIFEST
# v1 2011-08-14
# This is another comment
index.html
cache.html
style.css
image1.png
# Use from network if available
NETWORK:
network.html
# Fallback content
FALLBACK:
/ fallback.html
Který obsahuje tři části (nezáleží na pořadí a každá sekce se může vyskytnout
vícekrát nebo vůbec). První v ukázce je CACHE
, která určuje, jaké soubory se
mají cachovat. Tato sekce se nemusí explicitně uvádět, je to výchozí sekce (v
ukázce se jedná o index.html
, cache.html
, …). Další je NETWORK
, kde se
sděluje, které soubory se mají načítat z internetu. Vhodné například pro
skriptíky sledující návštěvnost. A pak tu je FALLBACK
sekce oznamující jakou
jinou stránku zobrazit, pokud požadovaná stránka v cache není.
Není to nic složitého. Jen si dejte pozor: zástupná znak hvězdičku nelze použít v sekci CACHE a ve FALLBACK sekci je první parametr prefix, pro které pravidlo platí; tedy lomítko znamená všechny stránky. Pro podrobnější popis hodím 303 na kapitolu Let’s take this offline z Dive Into HTML5.
V odkazovaném článku se jako ukázková aplikace popisuje Wikipedia s touto funkcionalitou: jakákoliv navštívená stránka se automaticky dostane do cache a pokud požadovaná stránka není dostupná, zobrazí se speciální stránka. To je pro „statický“ obsah s užitečnými informacemi dobré řešení.
Horší to je s dynamickým webem, kde není žádoucí cachovat každou stránku. Může se jednat o sociální síť, e-shop či jinou dynamickou aplikaci, kde se každá stránka zobrazuje s měnícími se stavy. Také by stránky mohli zbytečně zabírat spoustu místa. Proto cachování každé stránky v tomto případě postrádá smysl nebo by vedlo jen ke zmatení uživatele. Zde by dobrým řešením mohlo být jen sdělit fallback a jinak vše tahat čerstvé z internetu.
Něco takového bohužel nejde udělat, protože každá stránka obsahující manifest
je automaticky cachována aniž by se to explicitně uvedlo v manifestu. Nejde to
potlačit ani s hlavičkou Cache-Control: no-cache, no-store
. To je dost
nepříjemné a tato drobnost mi přijde jako velký nedostatek.
Hned by mohlo napadnout, že se manifest může dát jen na jednu určitou stránky a na ostatní nikoliv. Pravda, ale stále jedna stránka bude cachována a hlavně(!) uživatel musí danou stránku navštívit. Pokud uživatel tak neudělá, prohlížeč se nedozví o manifestu a offline verze jakoby neexistovala.
Řešení ale neleží daleko, jen se musí trochu hackovat – vytvořit offline
stránku, která jako jediná bude mít odkaz na manifest a nebude na offline
stránku nikde odkaz. Tuto stránku potom přibalit ke každé stránce v tagu
iframe
. Tím se zajistí, že online stránky se do cache nedostanou, a přitom
se o manifestu prohlížeč dozví z jakékoliv stránky. (Já říkal, že to bude
hack. ;))
K lepšímu řešení jsem se zatím nedobral ani po pátráním po internetu. Snad jednou bude možné hack zahodit a udělat to systémovější cestou.