loukl storidžTakélocal storage, window.localStorage, Web StoragePokročilý

Definice

LocalStorage je prohlížečové úložiště typu klíč–hodnota, které webové stránce umožňuje ukládat řetězce na disk uživatele bez data expirace. Data zůstávají po zavření záložky i restartu počítače, jsou oddělená podle původu (schéma, doména, port) a přistupuje se k nim synchronně z JavaScriptu přes rozhraní window.localStorage.

Kategorie: Webové technologieAktualizováno

Co LocalStorage řeší

LocalStorage vzniklo jako náhrada za zneužívání cookies k ukládání klientského stavu. Cookie se posílá s každým HTTP požadavkem, takže i pár kilobajtů preferencí zdražuje veškerou komunikaci. LocalStorage naproti tomu zůstává výhradně v prohlížeči: server o jeho obsahu neví, dokud ho aplikace sama neodešle. Kapacita je řádově vyšší, běžně kolem 5 MB na původ, zatímco cookie je limitována přibližně 4 KB.

Klíče, hodnoty a jediný datový typ

Úložiště zná jen řetězce. Uložení objektu proto znamená ruční serializaci přes JSON.stringify a při čtení JSON.parse. Číslo 42 se vrátí jako "42", hodnota null jako "null". API má pět metod: setItem, getItem, removeItem, clear a key, plus vlastnost length.

Původ jako hranice izolace

Data patří konkrétnímu původu. https://example.com a http://example.com jsou dva různé sklady, stejně jako jiný port. Subdomény se nesdílejí, takže app.example.com nevidí nic z www.example.com. Iframe z cizí domény má vlastní úložiště a moderní prohlížeče ho ve třetí straně často blokují úplně.

Persistence a mazání

Záznam nemá TTL. Zmizí, když ho smaže kód, uživatel vyčistí data prohlížeče, nebo když prohlížeč pod tlakem na místo úložiště vyhodí data málo používaných webů. V anonymním okně se obsah zahodí po zavření relace. Pro data, která mají vypršet, si expiraci musí aplikace uložit vedle hodnoty sama.

Kde LocalStorage brzdí

API je synchronní a běží na hlavním vlákně. Zápis většího JSONu blokuje vykreslování, což se projeví na skóre interaktivity. Web Worker k němu nemá přístup vůbec. Při větších objemech, binárních datech nebo potřebě dotazů je správnou volbou IndexedDB, u čistě relačních dotazů pak žádné klientské úložiště nestačí.

Bezpečnostní rozměr

Obsah LocalStorage je plně čitelný libovolným skriptem na stránce. Jediná úspěšná XSS zranitelnost znamená, že útočník přečte všechno, včetně uloženého tokenu. Cookie s příznaky HttpOnly a Secure je pro přihlašovací tokeny podstatně bezpečnější, protože k ní JavaScript nemá přístup. Do LocalStorage tedy patří preference, rozpracovaný formulář nebo obsah košíku, ne hesla, osobní údaje ani platební data. Ukládání identifikátorů pro sledování uživatele navíc spadá pod pravidla o přístupu k zařízení, takže vyžaduje souhlas stejně jako marketingová cookie.

Vztah k renderování na serveru

Při server-side renderingu objekt window na serveru neexistuje. Přímé volání localStorage.getItem v komponentě proto shodí build nebo způsobí neshodu mezi serverovým a klientským HTML. Řešením je čtení až po připojení komponenty do DOM, tedy v efektu běžícím na klientovi.

Sledování změn napříč záložkami

Prohlížeč vyvolá událost storage na oknech stejného původu, která zápis neprovedla. Díky tomu lze synchronizovat odhlášení nebo přepnutí motivu mezi otevřenými záložkami bez dotazu na server.

Příklady z praxe

  1. Uložení a čtení nastavení motivu

    Web si pamatuje, že uživatel přepnul na tmavý motiv. Hodnota se uloží při kliknutí a načte se při dalším startu aplikace, ještě před prvním vykreslením obsahu. Protože LocalStorage zná jen řetězce, boolean je potřeba převést ručně.

    // zápis
    localStorage.setItem('theme', 'dark');
    
    // čtení s výchozí hodnotou
    const theme = localStorage.getItem('theme') ?? 'light';
    document.documentElement.dataset.theme = theme;
    
    // složitější stav vyžaduje serializaci
    localStorage.setItem('prefs', JSON.stringify({ theme, fontSize: 16 }));
    const prefs = JSON.parse(localStorage.getItem('prefs') || '{}');
  2. Košík e-shopu přežije zavření prohlížeče

    E-shop drží obsah košíku v LocalStorage, takže se vrácenému návštěvníkovi zboží objeví i po restartu počítače. Zároveň si ukládá časové razítko, protože samotné API expiraci neumí, a po sedmi dnech položky zahodí. Autoritativní zůstává košík na serveru, klientská kopie jen šetří dotazy a snižuje riziko, že vznikne opuštěný košík.

    const KEY = 'cart';
    const TTL = 7 * 24 * 60 * 60 * 1000;
    
    function saveCart(items) {
      localStorage.setItem(KEY, JSON.stringify({ items, savedAt: Date.now() }));
    }
    
    function loadCart() {
      try {
        const raw = JSON.parse(localStorage.getItem(KEY) || 'null');
        if (!raw || Date.now() - raw.savedAt > TTL) return [];
        return raw.items;
      } catch {
        localStorage.removeItem(KEY);
        return [];
      }
    }

Časté omyly

MýtusLocalStorage je bezpečnější než cookies, protože se neposílá na server.
Ve skutečnostiLocalStorage je čitelné jakýmkoli JavaScriptem běžícím na stránce, takže jediné XSS vydá celý obsah útočníkovi. Cookie s příznakem HttpOnly je pro přihlašovací tokeny naopak nedostupná ze skriptu, a tedy odolnější.
MýtusNa LocalStorage se nevztahuje souhlas s cookies.
Ve skutečnostiEvropská pravidla o přístupu k informacím v koncovém zařízení jsou technologicky neutrální. Uložení identifikátoru pro analytiku nebo reklamu do LocalStorage vyžaduje souhlas stejně jako marketingová cookie; bez souhlasu projdou jen nezbytné technické záznamy.
MýtusLocalStorage má vždycky 5 MB, na které se dá spolehnout.
Ve skutečnostiLimit není v žádné normě pevně daný, liší se podle prohlížeče a prohlížeč může data málo navštěvovaných webů uvolnit při nedostatku místa. Překročení kvóty vyhodí výjimku QuotaExceededError, kterou je nutné odchytit.

Časté dotazy

Kdy použít LocalStorage a kdy raději IndexedDB?
LocalStorage se hodí na malé množství jednoduchých řetězcových hodnot: nastavení jazyka, motiv, poslední zvolený filtr, rozpracovaný formulář. Jakmile jde o desítky megabajtů, binární data typu obrázků, nebo o strukturu, v níž je potřeba vyhledávat podle více klíčů, je správnou volbou IndexedDB. IndexedDB je asynchronní, neblokuje hlavní vlákno a je dostupná i z Web Workeru. Praktické pravidlo zní: pokud hodnota nepřesáhne jednotky kilobajtů a čte se jednorázově při startu aplikace, LocalStorage stačí a je výrazně jednodušší na použití.
Jak LocalStorage funguje v anonymním režimu prohlížeče?
LocalStorage je v anonymním okně dostupné, ale izolované od běžného profilu a smazané při zavření celé anonymní relace. Aplikace tedy nevidí data uložená v normálním okně a naopak. Některé prohlížeče navíc v přísném režimu ochrany soukromí přístup k úložišti u vloženého obsahu třetích stran zcela blokují a volání setItem skončí výjimkou. Kód by proto měl přístup k úložišti obalit blokem try a mít funkční záložní chování, když zápis selže.
Proč se hodnota z LocalStorage vrací jako řetězec?
LocalStorage je definované jako mapa řetězec na řetězec, jiný datový typ neukládá. Prohlížeč každou hodnotu před uložením převede na řetězec, takže číslo 42 se vrátí jako "42" a objekt jako "[object Object]". Pro strukturovaná data je nutné použít JSON.stringify při zápisu a JSON.parse při čtení. Parsování je vhodné obalit blokem try, protože poškozený nebo ručně upravený záznam vyhodí výjimku a shodil by celou aplikaci hned při startu.
Lze zjistit, že jiná záložka zapsala do LocalStorage?
Prohlížeč při zápisu vyvolá událost storage ve všech ostatních oknech a záložkách stejného původu; okno, které změnu provedlo, událost nedostane. Objekt události nese klíč, starou a novou hodnotu i adresu stránky, která zápis provedla. Typické využití je synchronní odhlášení: jedna záložka smaže záznam o session a ostatní na to okamžitě zareagují přesměrováním na přihlášení. Stejným způsobem se dá přepnout barevný motiv nebo zneplatnit lokální mezipaměť bez dotazu na server.

Zdroje

  1. Window.localStorage(otevře se v novém okně)MDN Web Docs
  2. HTML Standard: Web storage(otevře se v novém okně)WHATWG
  3. Web Storage API(otevře se v novém okně)MDN Web Docs
  4. HTML Living Standard(otevře se v novém okně)WHATWG
  5. Web Storage(otevře se v novém okně)Wikipedia

Související pojmy

Potřebujete to vyřešit v praxi?

Poradíme, jak na to ve vašem projektu

Vysvětlit pojem je jedna věc, navrhnout kolem něj funkční řešení druhá. Ozvěte se a probereme, co dává smysl u vás.