forked from deianvasilev/diveintohtml5
-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathoffline.html
281 lines (202 loc) · 30.4 KB
/
offline.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
<!DOCTYPE html>
<meta charset=utf-8>
<title>Offline Web Applications - Dive Into HTML5</title>
<!--[if lt IE 9]><script src=j/html5.js></script><![endif]-->
<link rel=alternate type=application/atom+xml href=https://github.com/diveintomark/diveintohtml5/commits/master.atom>
<link rel=stylesheet href=screen.css>
<style>
body{counter-reset:h1 8}
</style>
<link rel=stylesheet media='only screen and (max-device-width: 480px)' href=mobile.css>
<link rel=prefetch href=index.html>
<p>Navigace: <a href=index.html>Domů</a> <span class=u>‣</span> <a href=table-of-contents.html#offline>Dive Into <abbr>HTML5</abbr></a> <span class=u>‣</span>
<h1><br>Pojďme offline</h1>
<p id=toc>
<p class=a>❧
<h2 id=divingin>Jdeme na to</h2>
<p class=f><img src=i/aoc-c.png alt=C width=110 height=108>o je offline webová aplikace? Na první pohled to zní jako protimluv. Webové stránky si stáhnete a zobrazíte. Stahování znamená dostupné připojení k síti. Jak můžete stahovat, když jste offline? Samozřejmě, že nemůžete. Ale <em>můžete</em> stahovat, když jste online. A přesně tak offline aplikace v <abbr>HTML5</abbr> fungují.
<p>Offline webová aplikace je jen seznam <abbr>URL</abbr> — <abbr>HTML</abbr>, <abbr>CSS</abbr>, JavaScriptu, obrázků a jakýchkoliv dalších souborů. Hlavní stránka offline webové aplikace na tento seznam (tzv. soubor manifestu) odkazuje. Je to vlastně obyčejný textový soubor umístěný na webovém serveru. Webový prohlížeč, který podporuje offline aplikace v <abbr>HTML5</abbr> si stáhne seznam <abbr>URL</abbr> ze souboru manifestu, stáhne samotné soubory, uloží je lokálně a udržuje je aktuální. Když poté zkusíte otevřít webovou aplikaci bez internetového připojení, webový prohlížeč automaticky zobrazí tyto lokálně uložené soubory.
<p>Zbytek práce je na vás, na webovém vývojáři. V <abbr>DOM</abbr>u je vlastnost, která vám řekne, zda jste online nebo offline. Existují události, které se zavolají při změně stavu připojení (chvíli jste offline a za minutu zase online, atd.). Ale to je tak všechno. Pokud vaše aplikace vytváří data nebo ukládá svůj stav, je na vás <a href=storage.html>je uložit lokálně</a>, když jste offline a pak je synchronizovat se serverem, když jste zase online. Jinak řečeno, <abbr>HTML5</abbr> vám sice umožní mít webovovou aplikaci offline, ale co ta aplikace pak bude dělat je na vás.
<table class=bc>
<caption>Podpora offline režimu</caption>
<thead>
<tr><th title="Internet Explorer">IE<th title="Mozilla Firefox">Firefox<th title="Apple Safari">Safari<th title="Google Chrome">Chrome<th>Opera<th>iPhone<th>Android
<tbody>
<tr><td>·<td>3.5+<td>4.0+<td>5.0+<td>10.6+<td>2.1+<td>2.0+
</table>
<p class=a>❧
<h2 id=manifest>Cache Manifest</h2>
<p>Offline webová aplikace se točí kolem souboru cache manifestu. Co je soubor manifestu? Je to seznam všech souborů, které by webová aplikace mohla potřebovat při práci v offline režimu. Stahování a ukládání těchto souborů zajistíte přidáním atributu <code>manifest</code> do elementu <code><html></code>.
<pre><code><!DOCTYPE HTML>
<html <mark>manifest="/cache.manifest"</mark>>
<body>
...
</body>
</html></code></pre>
<p>Soubor cache manifestu může být umístěn kdekoliv na webovém serveru, ale musí být posílán s content type <code>text/cache-manifest</code>. Pokud používáte webový server Apache, mělo by stačit přidat <a href=http://httpd.apache.org/docs/2.2/mod/mod_mime.html#addtype>příkaz <code>AddType</code></a> do souboru <code>.htaccess</code> v kořenovém adresáři vašeho webu:
<pre><code>AddType text/cache-manifest .manifest</code></pre>
<p>Potom ověřte, že jméno souboru cache manifestu končí na <code>.manifest</code>. Pokud používáte jiný webový server nebo jinak nastavený Apache, podívejte se do dokumentace serveru, jak se hlavička <code>Content-Type</code> nastavuje.
<div class="pf clear">
<h4>Zeptejte se profesora Značky</h4>
<div class=inner>
<blockquote class=note>
<p><span>☞</span>Q: Moje webová aplikace obsahuje více stránek. Musím mít atribut <code>manifest</code> v každé z nich nebo ho stačí dát na hlavní stránku?
<p>A: Každá stránka vaší webové aplikace musí mít atribut <code>manifest</code>, který odkazuje na cache manifest pro celou aplikaci.
</blockquote>
</div>
</div>
<p>Dobře, takže každá <abbr>HTML</abbr> stránka odkazuje na soubor cache manifestu a ten je posílán se správnou <code>Content-Type</code> hlavičkou. Ale co patří <em>do</em> souboru manifestu? Tady to teprve začíná být zajímavé.
<p>První řádek každého cache manifestu je:
<pre><code>CACHE MANIFEST</code></pre>
<p>Dále jsou všechny soubory manifestu rozděleny do tří částí: sekce “explicit”, sekce “fallback”, a sekce “online whitelist”. Každá sekce má svoji hlavičku na samostatném řádku. Pokud soubor manifestu neobsahuje žádné nadpisy sekcí, jsou všechny uvedené položky autaticky zařazeny do sekce “explicit”. Nezdržujme se teorií, mohla by vám z ní vybouchnout hlava.
<p>Takto vypadá validní soubor manifestu. Obsahuje tři položky: <abbr>CSS</abbr> soubor, soubor JavaScriptu a <abbr>JPEG</abbr> obrázek.
<pre><code>CACHE MANIFEST
/clock.css
/clock.js
/clock-face.jpg</code></pre>
<p>Tento soubor manifestu nemá žádné nadpisy sekcí, takže všechny uvedené položky jsou automaticky v sekci “explicit”. Tyto položky se automaticky stáhnou, uloží lokálně a v případě, kdy nebude dostupné připojení k síti, se použijí se místo svých online protějšků. Takže po načtení tohoto souboru manifestu si prohlížeč z kořenového adresáře webového serveru stáhne <code>clock.css</code>, <code>clock.js</code> a <code>clock-face.jpg</code>. Poté můžete odpojit síťový kabel, obnovit stránku a všechny tyto soubory budou dostupné offline.
<div class="pf clear">
<h4>Zeptejte se profesora Značky</h4>
<div class=inner>
<blockquote class=note>
<p><span>☞</span>Q: Musím v cache manifestu uvádět i <abbr>HTML</abbr> stránky?<br>
A: Ano i ne. Pokud je celá vaše webová aplikace obsažena v jedné stránce, ujistěte se jen, že ta stránka ukazuje pomocí atributu <code>manifest</code> na cache manifest. Pokud otevřete <abbr>HTML</abbr> stránku s atributem <code>manifest</code>, předpokládá se, že samotná stránka je součástí webové aplikace, takže není nutné ji uvádět do souboru manifestu. Nicméně, pokud se vaše webová aplikace skládá z více stránek, měli by jste je zapsat do souboru manifestu, jinak prohlížeč nebude vědět, že má stáhnout a uložit i další <abbr>HTML</abbr> stránky.
</blockquote>
</div>
</div>
<h3 id=network>Sekce Network</h3>
<p>Teď tu máme trochu složitější příklad. Předpokládejme, že chcete sledovat návštěvníky vaší hodinové aplikace pomocí skriptu <abbr>tracking.cgi</abbr>, který se volá z atributu <code><img src></code>. Cachování tohoto souboru by zmařilo sledování, takže tento soubor by se neměl cachovat ani být k dispozici offline. Lze to vyřešit takto:
<pre><code>CACHE MANIFEST
<mark>NETWORK:
/tracking.cgi</mark>
CACHE:
/clock.css
/clock.js
/clock-face.jpg</code></pre>
<p>Tento soubor cache manifestu obsahuje nadpisy sekcí. Řádek označený <code>NETWORK:</code> je začátek sekce “online whitelist”. Položky uvedené v této sekci nejsou nikdy cachovány a nebudou k dispozici offline. (Při pokusu je načíst v offline režimu dostaneme chybovou hlášku.) Řádek nadepsaný <code>CACHE:</code> je začátek sekce “explicit”. Zbytek souboru cache manifestu je stejný jako v předchozím příkladu. Všechny uvedené soubory budou cachovány a k dispozici i offline.
<h3 id=fallback>Záložní (fallback) sekce</h3>
<p>V souboru cache manifestu existuje ještě jeden typ sekce: záložní sekce. V této sekci můžete určit náhrady pro online zdroje, které nemohou být z jakéhokoliv důvodu cachovány nebo se je nacachovat nepodařilo. Ve specifikaci <abbr>HTML5</abbr> najdeme pěkný příklad použití fallback sekce:
<pre><code>CACHE MANIFEST
FALLBACK:
/ /offline.html
NETWORK:
*</code></pre>
<p>A co to dělá? Představme si web, který obsahuje miliony stránek, jako je třeba <a href=http://http://cs.wikipedia.org/wiki/Hlavn%C3%AD_strana>Wikipedie</a>. Není možné stáhnout celý web, a to ani nechceme. Ale předpokládejme, že je možné zpřístupnit <em>část</em> webu offline. Ale jak se rozhodneme, které stránky budeme cachovat? Co třeba takhle: každá stránka, kterou na této hypotetické offline Wikipedii navštívíme bude stažena a cachována. To by zahrnovalo každý encyklopedický článek, který jste kdy navštívili, každou diskuzi (kde můžete diskutovat o konkrétním encyklopedickém článku), a každou editační stránku, kde můžete ten encyklopedický článek upravovat.
<p>To je to, co dělá soubor cache manifestu. Předpokládejme, že každá <abbr>HTML</abbr> stránka (článek, diskuze, editace, historie) na Wikipedii ukazuje na tento soubor cache manifestu. Když jakoukoliv takovou stránku navštívíte, prohlížeč si řekne “hej, tahle stránka je část offline webové aplikace, znám už tuhle konkrétní?” Pokud prohlížeč zatím nikdy tento soubor cache manifestu nestáhnul, vytvoří novou appcache (zkratka pro “aplikační cache”), stáhne všechny zdroje uvedené v cache manifestu, a nakonec přidá aktuální stránku do appcache. Pokud prohlížeč už o tomto cache manifestu ví, tak jen přidá aktuální stránku do již existující appcache. Ať už tak nebo tak, stránka, kterou jste navštívili skončí v appcache. Tohle je důležité. Znamená to, že máte offline webovou aplikaci, která si “postupně” přidává stránky, když je navštívíte. Nemusíte tedy vypisovat každou <abbr>HTML</abbr> stránku do cache manifestu.
<p>Teď se podíváme na fallback sekci. Fallback sekce v tomto cache manifestu má jen jeden řádek. První část řádku (před mezerou) není <abbr>URL</abbr>. Ve skutečnosti to je šablona <abbr>URL</abbr>. Znak (<code>/</code>) odpovídá jakékoliv stránce na webu, ne jen hlavní stránce. Pokud zkusíte navštívit stránku, když jste offline, prohlížeč ji zkusí načíst z appcache. Pokud ji tam najde (protože jste ji navštívili, když jste byli online a byla tedy implicitně přidána do appcache), tak zobrazí nacachovanou kopii. Pokud prohlížeč stránku v appcache nenajde, místo vypsání chybové hlášky, zobrazí stránku <code>/offline.html</code>, jak je určeno v druhé polovině řádku.
<p>Nakonec se podíváme na network sekci. Network sekce má v tomto cache manifestu také jen jeden řádek, který obsahuje jen jeden znak (<code>*</code>). Tento znak má v network sekci speciální význam. Říká se mu “zástupný znak”. To je elegantní způsob jak říct, že cokoliv co není v appcache, se má stáhnout z originální webové adresy, pokud je dostupné připojení k internetu. To je důležité pro “neuzavřenou” offline webovou aplikaci. To znamená, že pokud procházíte tuto hypotetickou offline-aktivní Wikipedii <em>online</em>, prohlížeč bude standardně stahovat obrázky, videa a další vložené položky, i pokud jsou na jiné doméně. (To je běžné na velkých webech, i pokud nejsou součástí webové aplikace. <abbr>HTML</abbr> stránky jsou generovány a načítány lokálně a obrázky a videa jsou distribuovány z <a href=http://en.wikipedia.org/wiki/Content_delivery_network><abbr title="content delivery network">CDN</abbr></a> na jiné doméně.) Bez tohoto zástupného znaku by se naše offline-aktivní Wikipedie chovala divně, pokud by jste byli online — konkrétně by nenačítala jakékoliv externě uložené obrázky nebo videa!
<p>Je tento příklad kompletní? Ne. Wikipedie je víc než <abbr>HTML</abbr> soubory. Na každé stránce používá společné <abbr>CSS</abbr>, JavaScript a obrázky. Každý z těchto zdrojů by musel být explicitně uvedený v sekci <code>CACHE:</code> v manifest souboru, aby se stránky správně zobrazovaly a chovaly i offline. Účelem fallback sekce je to, že můžete mít “neuzavřenou” offline webovou aplikaci, která obsahuje i soubory, které nejsou explicitně uvedeny v souboru manifestu.
<p class=a>❧
<h2 id=events>Průběh událostí</h2>
<p>Zatím jsem o offline webových aplikacích, cache manifestu a offline aplikačním cache (“appcache”) mluvil vágně, skoro magicky. Věci se stahují, prohlíže rozhodují a všechno Prostě Funguje. Ale vy víte svoje, že? Vždyť mluvíme o tvorbě webů. Nikdy se nestane, aby to Prostě Fungovalo.
<p>Nejdříve si pojďme popsat průběh událostí, zvláště <abbr>DOM</abbr> událostí. Když prohlížeč načte stránku, která obsahuje cache manifest, zavolá na objektu <code>window.applicationCache</code> řadu událostí. Vím, že to vypadá komplikovaně, ale věřte mi, že je to nejjednodušší způsob, jak jsem to mohl popsat, bez toho abych vynechal důležité informace.
<ol>
<li>Hned jak prohlížeč zjistí existence atributu <code>manifest</code> v elementu <code><html></code>, zavolá událost <strong><code>checking</code></strong>. (Všechny zde popsané události jsou volané na objektu <code>window.applicationCache</code>). Událost <code>checking</code> je zavolána vždy, bez ohledu na to, jestli už jste předtím navštívili tuto stránku nebo nějakou jinou, která ukazuje na stejný soubor manifestu.
<li>Pokud váš prohlížeč vidí tento soubor cache manifestu poprvé...
<ul>
<li>Zavolá událost <strong><code>downloading</code></strong> a začne stahovat soubory uvedené v cache manifestu.
<li>Během stahování bude pravidelně volat událost <strong><code>progress</code></strong>, která bude obsahovat informace o tom, kolik souborů už bylo staženo a kolik jich ještě zbývá stáhnout.
<li>Poté, co se všechny soubory uvedené v cache manifestu stáhnou, prohlížeč zavolá poslední událost, <strong><code>cached</code></strong>. To je signál, že offline webová aplikace je celá nacachovaná a připravená k použití offline. Tak a je hotovo.
</ul>
<li>Na druhou stranu, pokud už jste předtím navštívili tuto nebo jinou stránku, která odkazuje na stejný soubor cache manifestu, prohlížeč už o něm ví a může už mít některé soubory uložené v appcache. Dokonce může mít v appcache uloženou celou offline webovou aplikaci. Otázkou je, zda se soubor cache manifestu změnil od posledního načtení prohlížečem.
<ul>
<li>Pokud se nezměnil, prohlížeč ihned zavolá událost <strong><code>noupdate</code></strong>. A hotovo.
<li>Pokud je odpověď ano, cache manifest <em>se</em> změnil, tak prohlížeč zavolá událost <strong><code>downloading</code></strong> a začne stahovat všechny soubory uvedené v cache manifestu.
<li>Během stahování prohlížeč průběžně volá událost <strong><code>progress</code></strong>, která obsahuje informaci o tom, kolik souborů už bylo staženo a kolik jich je ještě ve frontě ke stažení.
<li>Poté, co se všechny soubory uvedené v cache manifestu úspěšně znovustáhnou, prohlížeč zavolá poslední událost, <strong><code>updateready</code></strong>. To je signál, že nová verze vaší webové aplikace je zcela nacachovaná a připravená k použití offline. <em>Nová verze se nicméně ještě nepoužívá</em>. Abychom ji zapnuli bez nutnosti obnovit stránku, můžete ručně zavolat funkci <code>window.applicationCache.swapCache()</code>.
</ul>
</ol>
<p>Pokud během procesu dojte k jakékoliv chybě, prohlížeč zavolá událost <strong><code>error</code></strong> a zastaví. Následuje beznadějně nekompletní seznam toho, co se mohlo pokazit:
<ul>
<li>Cache manifest vrátil <abbr>HTTP</abbr> error 404 (Page Not Found) nebo 410 (Permanently Gone).
<li>Cache manifest byl nalezen nezměněný, ale <abbr>HTML</abbr> stránku, která na něj odkazuje se nepodařilo stáhnout.
<li>Cache manifest se změnil v průběhu aktualizace
<li>Cache manifest byl změněn a správně stažen, ale prohlížeči se nepodařilo stáhnout některý ze v něm uvedených souborů.
</ul>
<h2 id=debugging>Umění ladění, a.k.a. “Zabijte mě! Zabijte mě teď!”</h2>
<p>Chtěl bych zdůraznit dvě důležité věci. První je něco, co jste si právě přečetli, ale věřím, že je nutné to zopakovat znovu: když se nepodaří načíst byť i jediný soubor uvedený v cache manifestu, celý proces ukládání offline aplikace selže. Prohlížeč zavolá událost <code>error</code>, ale nebude na první pohled jasné, co je za problém. Kvůli tomu může být ladění offline webových aplikací více frustrující než obvykle.
<p>Druhá věc je něco, co technicky není chyba, ale dokud nepochopíte, jak to funguje, tak to bude vypadat jako bug v prohlížeči. Souvisí to s tím, jak přesně prohlížeč pozná, jestli se soubor cache manifestu změnil. Je to třífázový proces. Je to nudné, ale důležité, tak dávejte pozor.
<ol>
<li>Podle běžné sémantiky <abbr>HTTP</abbr> prohlížeč pozná, jestli vypršela platnost souboru cache manifestu. Webový server k němu, stejně jako k jakémukoliv jinému souboru přístupnému přes <abbr>HTTP</abbr>, přidá do <abbr>HTTP</abbr> hlaviček odpovědi další meta-informace. Některé z těchto <abbr>HTTP</abbr> hlaviček (<code>Expires</code> a <code>Cache-Control</code>) říkají prohlížeči, jak má dovoleno soubory cachovat bez dotazování se serveru na případné změny. Tento způsob cachování nemá nic společného s offline webovými aplikacemi. Funguje to úplně stejně s jakoukoliv <abbr>HTML</abbr> stránkou, stylem, skriptem, obrázkem nebo čímkoliv dalším na webu.
<li>Pokud vypršela platnost cache manifestu (podle jeho <abbr>HTTP</abbr> hlaviček), tak se prohlížeč zeptá serveru, zda existuje novější verze a pokud ano, tak ji prohlížeč stáhne. Prohlížeč to udělá tak, že pošle <abbr>HTTP</abbr> požadavek, který bude obsahovat datum a čas poslední změny cache manifestu, kterou webový server poslal ve hlavičkách <abbr>HTTP</abbr> odpovědi při minulém stažení. Pokud webový server zjistí, že se cache manifest od toho data nezměnil, tak jen vrátí status <code>304 (Not Modified)</code>. Tohle opět není specifické pro offline webové aplikace, ale funguje to tak prakticky se všemi soubory na webu.
<li>Pokud se podle webového serveru soubor cache manifestu od tohoto data změnil, vrátí <abbr>HTTP</abbr> status <code>200 (OK)</code> následovaný obsahem nového souboru a novými <code>Cache-Control</code> hlavičkami a s novým datem poslední změny, takže kroky 1 a 2 budou příště fungovat správně. (<abbr>HTTP</abbr> je cool; webové servery vždy myslí na budoucnost. Pokud už webový server musí poslat soubor, udělá cokoliv, aby zajistil, že ho nebude muset bezdůvodně posílat znovu.) Hned, jak prohlížeč stáhne nový soubor cache manifestu, prohlížeč porovná jeho obsah s tím, který stáhnul posledně. Pokud je obsah souboru cache manifestu stejný jako byl minule, prohlížeč znovu nestáhne žádný z uvedených souborů.
</ol>
<p>Kterýkoliv z těchto kroků vám může způsobit nepříjemnosti při vývoji a testování vaší offline webové aplikace. Například řekněme, že nasadíte jednu verzi cache manifestu, a o 10 minut později zjistíte, že do něj potřebujete přidat další soubor. Žádný problém, že? Jen přidáme další řádek a znovu nasadíme. Aj. Dojde k tomuto: obnovíte stránku, prohlížeč zjistí existenci atributu <code>manifest</code>, zavolá událost <code>checking</code> a pak... nic. Prohlížeč tvrdohlavě trvá na to, že soubor cache manifestu se nezměnil. Proč? Protože, ve výchozím nastavení, je webový server pravděpodobně nastaven tak, aby prohlížeči říkal (pomocí <abbr>HTTP</abbr> sémantiky za použití hlaviček <code>Cache-Control</code>), že statické soubory má cachovat několik hodin. To znamená, že prohlížeč se nikdy v tomto procesu nedostane za krok 1. Webový server samozřejmě ví, že se soubor změnil, ale prohlížeč se nikdy nedostane ani tak daleko, aby se ho zeptal. Proč? Protože když si prohlížeč naposledy stahovat soubor cache manifestu, webový server mu řekl (pomocí <abbr>HTTP</abbr> sémantiky za použití hlaviček <code>Cache-Control</code>), aby si ho několik hodin cachoval. A teď, o 10 minut později přesně to prohlížeč dělá.
<p>Aby bylo jasno, tohle není chyba, ale vlastnost. Všechno funguje přesně tak, jak má. Kdyby webové server neměl možnost, jak říct prohlížečům (a proxy serverům), aby cachovaly, web by se přes noc zhroutil. To pro vás asi není žádná útěcha, po několika hodinách strávenými zkoumáním, proč si prohlížeč nevšiml změněného cache manifestu. (A ještě ke všemu, pokud počkáte dostatečně dlouho, tak to záhadně začne fungovat! Protože vypršela platnost <abbr>HTTP</abbr> cache! Přesně tak, jak má! Teď mě můžete zabít!)
<p>Skoro určitě musíte udělat toto: přenastavit webový server tak, aby váš soubor cache manifestu nebyl cachovatelný pomocí <abbr>HTTP</abbr>. Pokud máte webový server Apache, stačí na to dva řádky v souboru <code>.htaccess</code>:
<pre><code>ExpiresActive On
ExpiresDefault "access"</code></pre>
<p>To skutečně vypne cachování všech souborů v daném adresáři a všech podadresářích. To pravděpodobně není to, co by jste chtěli na produkčním serveru, takže by jste to měli buď omezit pomocí direktivy <code><Files></code>, aby to platilo pouze pro soubor cache manifestu a nebo můžete vytvořit podadresář, který bude obsahovat jen soubor <code>.htaccess</code> a cache manifest. Jako obvykle, detaily nastavení jsou pro každý webový server jiné, takže se na řízení cachovacích <abbr>HTTP</abbr> hlaviček podívejte do manuálu.
<p>I když vypnete <abbr>HTTP</abbr> cachování souboru cache manifestu, pořád budete narážet na to, když změníte některý ze souborů uložených v appcache, který bude stále dostupný na stejné <abbr>URL</abbr> na webovém serveru. Tady vám to zkazí 2. krok procesu. Pokud se nezměnil soubor cache manifestu, prohlížeč nezjistí, že se změnil některý z dříve nacachovaných souborů. Podívejte se na následující příklad:
<pre><code>CACHE MANIFEST
# rev 42
clock.js
clock.css</code></pre>
<p>Pokud změníte <code>clock.css</code>, tak neuvidíte změny, protože samotný soubor cache manifestu se nezměnil. Pokaždé, když změnít některý ze souborů ve vaší offline webové aplikaci, budete muset změnit také soubor cache manifestu. Může to být změna i jen jediného znaku. Nejjednodušší způsob jak toho dosáhnout je, podle mě, přidání řádku komentáře, který bude obsahovat aktuální číslo revize. Změníte číslo revize v komentáři, webový soubor vrátí nový soubor cache manifestu, prohlížeč zjistí, že se obsah souboru změnil a nastartuje proces znovustažení všech souborů v něm uvedených.
<pre><code>CACHE MANIFEST
<mark># rev 43</mark>
clock.js
clock.css</code></pre>
<p class=a>❧
<h2 id=halma>Pojďme jednu napsat!</h2>
<p>Vzpomínáte si na Halmu, kterou jsme si ukázali v <a href=canvas.html#halma>kapitole o canvasu</a> a potom vylepšili <a href=storage.html#halma>ukládáním stavu do trvalého lokálního úložiště</a>? Pojďme ji ještě vylepšit a udělat ji offline.
<p>Na to potřebujeme cache manifest, který bude obsahovat vše, co hra potřebuje. Máme hlavní <abbr>HTML</abbr> stránku, jeden JavaScriptový soubor, který obsahuje všechen kód hry a… to je vše. Nejsou tam žádné obrázky, protože všechno je vykreslováno programově, přes <a href=canvas.html>canvas <abbr>API</abbr></a>. Všechny potřebné <abbr>CSS</abbr> styly jsou v elementu <code><style></code> v hlavičce <abbr>HTML</abbr> stránky. Nás cache manifest vypadá takto:
<pre><code>CACHE MANIFEST
halma.html
../halma-localstorage.js</code></pre>
<p>Něco málo k cestám. Vytvořil jsem podadresář <code>offline/</code> v adresáři <code>examples/</code> a soubor cache manifestu je uložený v něm. Protože <abbr>HTML</abbr> stránka potřebuje drobnou úpravu, aby fungovala offline (k tomu se dostaneme později), vytvořil jsem samostatnou kopii <abbr>HTML</abbr> souboru, která je také uložena v podadresáři <code>offline/</code>. Protože není potřeba nic měnit v tom JavaScriptovém kódu, kam jsme <a href=storage.html#halma>přidali podporu local storage</a>, využijeme ten stejný soubor, který je v nadřazeném adresáři (<code>examples/</code>). Soubory tedy vypadají takto:
<pre><samp>/examples/localstorage-halma.html
/examples/halma-localstorage.js
/examples/offline/halma.manifest
/examples/offline/halma.html</samp></pre>
<p>V souboru cache manifestu (<code>/examples/offline/halma.manifest</code>) chceme odkázat na dva soubory. Nejprve na offline verzi <abbr>HTML</abbr> souboru (<code>/examples/offline/halma.html</code>). Protože tyto dva soubory jsou v jednom adresáři, je v souboru manifestu uveden bez jakékoliv cesty. Poté, soubor JavaScriptu, který je uložen v nadřazeném adresáři (<code>/examples/halma-localstorage.js</code>). Ten je v souboru manifestu zapsán pomocí relativní <abbr>URL</abbr>: <code>../halma-localstorage.js</code>. Je to stejné, jako by jste použili relativní <abbr>URL</abbr> v atributu <code><img src></code>. Jak uvidíte v dalším příkladě, můžete použít i absolutní cesty (začínající v kořeni aktuální domény) a nebo dokonce absolutní <abbr>URL</abbr> (odkazující na soubory na jiných doménách).
<p>Teď potřebujeme v <abbr>HTML</abbr> souboru přidat atribut <code>manifest</code>, který bude ukazovat na soubor cache manifestu.
<pre><code><!DOCTYPE html>
<html lang="en" <mark>manifest="halma.manifest"</mark>></code></pre>
<p>A je to! Když prohlížeč s podporou offline režimu poprvé načte <a href=examples/offline/halma.html>offline přístupnou <abbr>HTML</abbr> stránku</a>, tak stáhne soubor manifestu a začne stahovat všechny odkazované soubory a ukládat je v appcache. Od této chvíle se při každé návštěvě stránku bude spouštět výše popsaný algoritmus offline aplikace. Můžete hru hrát offline a protože si pamatuje svůj stav, můžete ji kdykoliv zavřít a přijít zpět a pokračovat tam, kde jste skončili.
<p class=a>❧
<h2 id=further-reading>Další čtení</h2>
<p>Standardy:
<ul>
<li><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html>Offline web applications</a> in the <abbr>HTML5</abbr> specification
</ul>
<p>Dokumentace výrobců prohlížečů:
<ul>
<li><a href=https://developer.mozilla.org/En/Offline_resources_in_Firefox>Offline resources in Firefox</a>
<li><a href=http://developer.apple.com/safari/library/documentation/iPhone/Conceptual/SafariJSDatabaseGuide/OfflineApplicationCache/OfflineApplicationCache.html><abbr>HTML5</abbr> offline application cache</a>, part of the <a href=http://developer.apple.com/safari/library/documentation/iPhone/Conceptual/SafariJSDatabaseGuide/Introduction/Introduction.html>Safari client-side storage and offline applications programming guide</a>
</ul>
<p>Tutoriály a dema:
<ul>
<li><a href=http://googlecode.blogspot.com/2009/04/gmail-for-mobile-html5-series-using.html>Gmail for mobile <abbr>HTML5</abbr> series: using appcache to launch offline - part 1</a>
<li><a href=http://googlecode.blogspot.com/2009/05/gmail-for-mobile-html5-series-part-2.html>Gmail for mobile <abbr>HTML5</abbr> series: using appcache to launch offline - part 2</a>
<li><a href=http://googlecode.blogspot.com/2009/05/gmail-for-mobile-html5-series-part-3.html>Gmail for mobile <abbr>HTML5</abbr> series: using appcache to launch offline - part 3</a>
<li><a href=http://jonathanstark.com/blog/2009/09/27/debugging-html-5-offline-application-cache/>Debugging <abbr>HTML5</abbr> offline application cache</a>
<li><a href=http://hacks.mozilla.org/2010/02/an-html5-offline-image-editor-and-uploader-application/>an HTML5 offline image editor and uploader application</a>
<li><a href=http://www.20thingsilearned.com/>20 Things I Learned About Browsers and the Web</a>, an advanced demo that uses the application cache and other <abbr>HTML5</abbr> techniques
</ul>
<p class=a>❧
<p>This has been “Let’s Take This Offline.” The <a href=table-of-contents.html>full table of contents</a> has more if you’d like to keep reading.
<div class=pf>
<h4>Did You Know?</h4>
<div class=moneybags>
<blockquote><p>In association with Google Press, O’Reilly is distributing this book in a variety of formats, including paper, ePub, Mobi, and <abbr>DRM</abbr>-free <abbr>PDF</abbr>. The paid edition is called “HTML5: Up & Running,” and it is available now. This chapter is included in the paid edition.
<p>If you liked this chapter and want to show your appreciation, you can <a href="http://www.amazon.com/HTML5-Up-Running-Mark-Pilgrim/dp/0596806027?ie=UTF8&tag=diveintomark-20&creativeASIN=0596806027">buy “HTML5: Up & Running” with this affiliate link</a> or <a href=http://oreilly.com/catalog/9780596806033>buy an electronic edition directly from O’Reilly</a>. You’ll get a book, and I’ll get a buck. I do not currently accept direct donations.
</blockquote>
</div>
</div>
<p class=c>Copyright MMIX–MMXI <a href=about.html>Mark Pilgrim</a>
<form action=http://www.google.com/cse><div><input type=hidden name=cx value=013556084273090989037:f1s-wnbz68q><input type=hidden name=ie value=UTF-8><input type=search name=q size=25 placeholder="powered by Google™"> <input type=submit name=sa value=Hledat></div></form>
<script src=j/jquery.js></script>
<script src=j/modernizr.js></script>
<script src=j/dih5.js></script>
<script type="text/javascript"><!--
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-25728182-1']);
_gaq.push(['_setDomainName', '.html5.cz']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
// --></script>