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

Zdroják » Webdesign » Webdesignérův průvodce po HTML5: WebStorage

Webdesignérův průvodce po HTML5: WebStorage

Články Webdesign

Technologie počítané do „rodiny HTML5“ zahrnují kromě nových elementů a API k funkcím jako je geolokace i možnost provozování offline aplikací, jak jsme si naznačili v minulém článku. Ovšem aplikační cache je jen jedna část offline aplikace. Druhá, neméně důležitá, je ukládání dat na straně klienta.

V minulém článku o AppCache jsme si ukázali možnosti, které mají moderní prohlížeče v oblasti cachování skriptů a souborů na straně klienta. Ukázali jsme si, jak lze celkem jednoduše určit, že mají být soubory uloženy lokálně, které to mají být a jak s nimi nakládat. Ovšem většina aplikací potřebuje nejen ukládat stránky, skripty a další soubory („program files“), ale i nějak ukládat vytvořená data. A pokud má fungovat offline (nebo rychle), musí k tomuto účelu mít lokální úložiště. Technologie z rodiny HTML5 nabízí hned několik řešení, v tomto článku se podíváme na jedno z nich, konkrétně WebStorage.

WebStorage

Pravděpodobně nejjednodušší a nejrozšířenější technologií lokálních úložišť je WebStorage – podle webu Can I Use můžeme použít WebStorage v nových verzích všech hlavních prohlížečů (IE od verze 8, FF od 3.0, Safari od 4.0, Chrome od 3.0 a Opera od verze 10.5), i když to s tou podporou není stoprocentní, jak si řekneme dál – pozn.aut.

Web Storage definuje dvě lokální úložiště, které jsou identické až na jednu věc, a tou je jejich perzistence. První úložiště, zvané LocalStorage, ukládá data v prohlížeči „napořád“ – tedy dokud nejsou skriptem smazány. Druhé úložiště, SessionStorage, ukládá data jen po dobu trvání sezení (session), tedy zhruba řečeno po dobu než uživatel zavře prohlížeč, okno nebo záložku s danou stránkou. Specifikace výslovně dodává, že „trvání sezení“ nemusí být totožné s dobou otevření příslušného okna či záložky a že některé prohlížeče mohou nabízet i pokračování v sezení po restartu.

Úložiště pracují jako jednoduchá key-value databáze a jejich fungování lze připodobnit k „asociativním polím“ – tedy polím dat, které jsou indexovány nikoli celočíselnou hodnotou, ale obecným klíčem, nejčastěji řetězcem. Tato pole existují ve většině moderních jazyků, i když pod různými názvy – asociativní pole, slovníky či hash arrays jsou nejčastější pojmenování.

Ukládání v prohlížeči podle klíčů může připomínat cookies, ovšem je tu jeden zásadní rozdíl: Cookies jsou primárně určeny pro data, která si chce server uložit do klientského prohlížeče pro své účely (i když jsou přístupné ze skriptu, běžícího v prohlížeči). Posílají se v hlavičkách HTTP dotazů a odpovědí a jejich velikost je omezená. Data uložená ve WebStorage naproti tomu zůstávají v prohlížeči, nikam se neposílají a o případné uložení na server se musí programátor postarat sám.

Specifikace rovněž neurčuje velikost těchto úložišť a nechává správu a případné omezení kapacity na tvůrcích prohlížečů. Nelze se tedy spoléhat na to, že existuje nějaká „specifikací daná minimální nebo maximální kapacita“. Doporučená velikost úložiště je 5MB pro každý zdroj (doménu).

Umí váš prohlížeč WebStorages? Zjistíte to rychle a přehledně v našem detektoru podpory technologií z rodiny HTML5. Naleznete v něm i odkazy na další články, které se zabývají tímto tématem.

Bezpečnost a konzistence dat

Podobně jako u cookies a JavaScriptu platí i pro WebStorage pravidlo same origin na základě domény, a specifikace doporučuje tvůrcům prohlížečů postupy, jak zabránit neoprávněným skriptům přistupovat k uloženým datům. Pro hostingy, které nabízí běh webů pro různé uživatele na společné doméně, jako byl třeba známý server Geocities, se použití WebStorage nedoporučuje – specifikace podotýká, že i kdyby některý prohlížeč implementoval ochranu podle cesty k souboru, tak existují způsoby, ji jak pomocí manipulace s DOM obejít.

Na tomto místě je vhodné podotknout, že Local Storage je opravdu sdílené pro celý zdroj. Pokud si uživatel otevře tutéž stránku v několika oknech či panelech, tak všechny přistupují k jednomu úložišti. Pokud tedy skript v jednom okně změní data, uvidí tyto změny i skripty v dalších otevřených oknech. Totéž platí např. i pro obsluhu událostí: Pokud ve skriptu obsluhujeme událost storage, viz dále, a uživatel si aplikaci otevře v několika oknech, pak změna dat v jednom z nich vyvolá obsluhu této události ve všech.

Ohledně konzistence dat je důležité vědět následující: Specifikace nepožaduje, aby změny byly ihned ukládány na disk. Pokud si prohlížeč ukládá změny do cache v paměti a havaruje před jejím uložením na disk, může uživatel o data přijít. Specifikace vyžaduje pouze konzistenci dat při paralelním přístupu z více oken najednou (viz předchozí odstavec).

Programové rozhraní – API

K WebStorage lze přistupovat pomocí několika metod a vlastností, definovaných v rozhraní Storage. Jednotlivé položky jsou identifikovány jedinečným řetězcem – klíčem.

  • setItem(key, value) umožňuje nastavit položku s klíčem key (typ řetězec) na hodnotu value (obecný objekt). Jako v jiných jazycích i zde je existující položka se zadaným klíčem přepsána, neexistující vytvořena. Pokud nemůže být vytvořena, vyvolá metoda výjimku QUOTA_EXCEEDED_ERR. Technicky je při ukládání nejprve vytvořen klon (structured clone) předaného objektu a ukládán je až ten. Operace setItem() je atomická, tzn. pokud dojde v jakékoli fázi provádění k chybě, je vyhozena výjimka a uložená data zůstanou beze změny.
  • getItem(key) slouží ke čtení uložené hodnoty. Pokud položka s daným klíčem neexistuje, je vrácena hodnota  null.
  • removeItem(key) odstraní položku s daným klíčem z úložiště. Pokud neexistuje, neudělá nic. I removeItem()  je, podobně jako setItem(), atomická operace.
  • clear() slouží k vyčištění úložiště – pokud obsahuje nějaká data, jsou odstraněna.
  • key(index) vrátí klíč N-té položky v úložišti. Položky jsou interně číslovány od nuly a jejich počet můžeme zjistit z vlastnosti length. Pomocí key() a length můžeme tedy iterativně procházet uložené položky, podobně jako u jiných kolekcí v JavaScriptu.

Úložiště nabízí i již zmíněnou vlastnost length. Ta je určena pouze ke čtení, a jak už její název napovídá, dozvíme se z ní počet položek, uložených v úložišti.

Při změnách v úložišti je vyvolána událost storage. Tuto událost můžeme běžným způsobem zachytit a zjistit z ní informace o proběhlé operaci. V těle události nalezneme pak následující atributy:

  • key  – klíč položky, které se operace týkala
  • oldValue  – původní hodnota položky (byla-li měněna existující), nebo null, pokud byla položka vytvořena nově
  • newValue  – nová hodnota položky
  • url  – URL stránky se skriptem, který vyvolal událost
  • storageArea  – oblast, v níž došlo ke změně (local/session storage)

Poznámka a oprava: Událost storage zatím není v některých prohlížečích implementována zcela správně. Např. FF3.6.8 událost vyvolá, ale hodnoty jsou undefined, v Chrome 5.0.375 událost nebyla vyvolána. V současnosti tedy není obsluha události storage všeobecně použitelná (lze ji ale např. použít ve webových aplikacích pro iPhone), i když prohlížeče úložiště samotné implementují.

Aktualizace: V komentářích se objevilo řešení, které by mělo fungovat i v dalších prohlížečích (test) – díky:

  document.onstorage = spracuj;
  document.onstoragecommit = spracuj;
  if (window.addEventListener) {
    addEventListener('storage',spracuj,false);
    }
    else if (window.attachEvent) {
        attachEvent('onstorage',spracuj);
    }

Přístup k úložištím

Už jsme si říkali, že WebStorage nabízí dvě úložiště – Local Storage a Session Storage. Tato úložiště jsou implementována jako atributy objektu window, konkrétně window.localStorage a window.sessionStorage. Přistupovat k nim lze i přímo, tedy bez „window“, například takto:

sessionStorage.setItem("username", "John Doe");

nebo

var reloads = localStorage.getItem("reloadCounter");

Můžete se podívat na několik testovacích skriptů: test Session Storage, test Local Storage, výpis hodnot.

Úložiště jako pole

K úložištím je možno přistupovat nejen pomocí metod objektu Storage, ale i jako k polím, kdy jsou metody setItem(), resp. getItem(), volány transparentně na pozadí. Výše uvedené příklady můžeme tedy přepsat do podoby:

sessionStorage["username"] = "John Doe"

či

var reloads = localStorage["reloadCounter"];

Storages ale nedefinují iterátor, nemůžeme tudíž k procházení uložených hodnot použít konstrukci for( .. in ..). (Lze sice poměrně snadno iterátor doimplementovat, ale přepisování prototypů systémových objektů není ukázka příliš dobrého vychování. – pozn.aut.)

Krátká odbočka k offline aplikacím

Máme AppCache, která udrží soubory naší aplikace v prohlížeči i když je offline. Máme WebStorage, kam můžeme ukládat data. K tomu, abychom mohli vytvořit offline aplikaci, potřebujeme už jen detail: Zjistit, zda je uživatel online nebo offline a podle toho se zařídit. K tomu slouží vlastnost navigator.onLine, která má hodnotu buď true (=prohlížeč je online), nebo false (=prohlížeč je offline). Kromě toho můžeme využít i obsluhu událostí online a offline, které jsou vyvolány u dokumentu v případě, že prohlížeč přejde do režimu online (či do režimu offline). Jednoduchou konstrukcí typu

document.body.addEventListener("online", function () {...}, false);

můžeme tuto událost zachytit, a např. po přechodu do online módu můžeme obsah lokálního úložiště synchronizovat se serverem, můžeme nahrát na server obsah cache apod.

Shrnutí

WebStorages jsou v současné době poměrně přijatelná metoda pro ukládání dat na straně klienta. Ve spojení s minule popsanou AppCache nabízí poměrně slušné možnosti k vytváření webových aplikací, které jsou schopny pracovat i bez připojení (typicky mobilní telefony). V hlavních dnes používaných prohlížečích jsou implementovány, až na událost storage, u níž je funkčnost nejistá, což ale pravděpodobně ve většině aplikací nebude představovat nijak zásadní problém. Není proto žádný důvod se používání WebStorage ve webových aplikacích, určených primárně pro moderní prohlížeče, bránit.

Doporučené čtení k tématu:

Komentáře

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

„(Opera 10.60, Chrome 5.0.375) událost nevyvolaly.“
Treba tú udalosť „správne“ zaregistrovať.
Ja som použil nasledujúci kód, pre zaregistrovanie funkcie spracuj, a ten fungoval všade:

  document.onstorage = spracuj;
  document.onstoragecommit = spracuj;
  if (window.addEventListener) {
    addEventListener('storage',spracuj,false);
    }
    else if (window.attachEvent) {
        attachEvent('onstorage',spracuj);
    } 

Možno sa to dá ešte skrátiť, kód bol vytvorený len pokusmi.
Prehliadače sa ešte líšia v tom, či vyvolajú udalosť na tom istom okne.
V iných oknách tú udalosť vyvolajú.

_

Skúšal si to pre iné okno?
Pre to isté okno to vyvolané byť nemusí – má to istý zmysel.

fos4

V chromu se ta udalost spracuj vyvola ale ne v tom samem okne, pouze v tech jinych.

_

Ak sa otvorí viac okien s tým testovacím kódom, tak to funguje aj v Chrome, no nie pre okno, v ktorom udalosť vznikla.

_

Má to istú logiku.
Ak okno v tom objekte niečo zmení, tak už o tom automaticky „vie“, nemusí mu to byť oznámené.
Ostatným oknám to musí byť oznámené.
Snáď sa časom registrácia udalosti aj toto správanie zjednotí.

_
_

Ak sa použije iframe, tak sa udalosť vyvolá v tom istom okne aj v Chrome – v tom iframe.

fos4

Takže řešení je navěsit události nejen na window ale i document, to je bordel :-)
Jinak na jaké další díly HTML5 se můžeme těšit ?

Já

Text názoru je povinný

xstanda

To spracuj je tam protoze je autor slovak? Nebo je to preklep?

Já
3. 8. 2010 13:15 smazal Petr Krčmář, důvod: Klasický a tradiční spam s Viagrou.
Mikuláš Dítě

Stojí za zmínku, že IE8, IE9 platform preview ani Firefox nepodporují WebStorage pro protokol file:///. Localhost i ostatní http (třeba 127.0.0.1) funguje.

LuKo

Lze obsah LocalStorage smazat z prohlížeče? Pokud by to nešlo, lze to celkem snadno použít místo cookies k identifikaci uživatele. Cookie smaže a je z něj zase anonym. O tomto 99,9 % BFU nemá ponětí, navíc pokud by to nešlo mazat, pak by to byla téměř 100% identifikace.

_

Pri kompletnom zmazaní histórie sa vo FF zmaže aj localStorage.
Cez about:config sa dá táto funkčnosť veľmi jednoducho vypnúť.
Pri použití FF pridanému k balíčku s najznámejším anonymizérom je localStorge vypnuté.

MilosNemec

Díky za dobrý článek.
Za zmínku možná stojí, že vlastnost navigator.onLine nic neříká o tom, jestli je uživatel skutečně online nebo offline. Jen kopíruje offline mód prohlížeče. Takže můžete třeba vesele pracovat oproti lokálnímu web serveru, bez připojení k internetu, vlastnost navigator.onLine ale bude vracet true a žádná data neodešlete. Takže bych online stav raději testovat nějak jinak, třeba HTTP requestem přímo na server.

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.