IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 6 - Datová úložiště v JavaScriptu

V předešlém cvičení, Řešené úlohy k 4.-5. lekci OOP v JavaScriptu, jsme si procvičili nabyté zkušenosti z předchozích lekcí.

V dnešní lekci si představíme jakými způsoby můžeme v JavaScriptu ukládat data tak, abychom je při obnovení stránky hned zas neztratili.

localStorage v JavaScriptu - Objektově orientované programování v JavaScriptu

Web storage

Web storage, neboli DOM Storage, je souhrnný název pro úložiště localStorage a sessionStorage.

localStorage

localStorage je úložiště v internetovém prohlížeči uživatele (proto local), do kterého se mohou ukládat data v textovém řetězci, ke kterým můžeme později přistupovat. K dispozici máme pro naši aplikaci 10MB prostoru, což je pro texty opravdu hodně :) Možnost ukládat jen text je poměrně omezující, ale stejně je localStorage kvůli své jednoduchosti nejoblíbenějším úložištěm dat, o která nechceme po obnovení nebo zavření stránky přijít.

Práce s localStorage

S localStorage se pracuje velmi jednoduše.

setItem()

K uložení nějakého řetězce pod textový index použijeme metodu setItem(). Zkusme si pod klíč "jmeno" uložit string "Karel":

localStorage.setItem("jmeno", "Karel");

Stránku se skriptem otevřeme v prohlížeči, kód následně smažeme a stránku zas obnovíme. Tím jsme si jistí, že Karla již nikde v kódu nemáme, ale je uložený v úložišti.

getItem()

Analogicky pro přečtení hodnoty pod klíčem použijeme getItem(). Nyní si vypíšeme co je pod klíčem "jmeno", čímž získáme hodnotu "Karel":

document.write(localStorage.getItem("jmeno"));

Výsledek:

Tvoje stránka
localhost

Vidíme, že se Karel opravdu načetl.

removeItem()

Asi vás nepřekvapí, že řetězec pod nějakým klíčem můžeme z úložiště i vymazat. Uděláme to metodou removeItem():

localStorage.removeItem("jmeno");
clear()

Úložiště můžeme kompletně vyprázdnit od všech klíčů a dat pod nimi metodou clear().

length

Počet položek v localStorage získáme pomocí vlastnosti length:

document.write("Uloženo " + localStorage.length + " položek");

Výsledek:

Tvoje stránka
localhost
key()

Možná vás napadlo, jak zjistíme, co vše je v localStorage uloženo nebo jak s položkami v úložišti pracovat hromadně. Poslední chybějící metoda je proto key(n), kde n je index - pořadové číslo klíče, který chceme vrátit. V kombinaci s vlastností length tak dokážeme např. vypsat všechny klíče v úložišti a hodnoty pod nimi uložené. Udělejme si poslední ukázku, čímž opravdu vyčerpáme možnosti, které localStorage nabízí:

for (let i = 0; i < localStorage.length; i++) {
    const klic = localStorage.key(i);
    document.write(klic + ": " + localStorage.getItem(klic) + "<br>");
}

Výsledek:

Tvoje stránka
localhost

Kód uloží do localStorage 3 hodnoty pod 3 klíče a následně vypíše počet položek v úložišti.

Pořadí klíčů může být v každém prohlížeči jiné a proto by na něm naše aplikace neměla záviset. Neměli bychom tedy např. předpokládat, že prvně přidaná hodnota bude vždy pod klíčem 0.

Uložení více hodnot pod jeden klíč

Možná přemýšlíte, jakým způsobem je možné uložit např. pole hodnot nebo objekt pod jeden klíč úložiště? Pokud bychom související hodnoty neseskupovali pod jeden klíč, byl by v úložišti opravdu nepořádek, jen si zkuste představit, jak bychom tam uložili 2 uživatele. Proto si celý objekt převedeme na text, což se v JavaScriptu dělá pomocí formátu JSON. To se naučíme hned v příští lekci a potom si to i prakticky vyzkoušíme na našem OOP diáři.

sessionStorage

Kromě localStorage existuje také úložiště sessionStorage. To funguje úplně stejně, ale liší se v kontextu, v kterém jsou data uložena. Rozdíly jsou 3:

  • Data v sessionStorage jsou unikátní pro každou záložku prohlížeče. Když si naopak otevřeme tu samou stránku používající localStorage ve více záložkách, budou všechny záložky používat to samé úložiště s těmi stejnými daty.
  • Data budou ztracena ve chvíli zavření záložky. Naopak data v localStorage v prohlížeči zůstávají.
  • Říkáte si proč tedy sessionStorage používat, když se se zavřením stránky stejně smaže? To už bychom přeci mohli data uložit jen do proměnných jako doposud... sessionStorage podobně jako cookies zůstává netknuté při obnovení stránky nebo při přechodu na jinou stránku v té samé doméně.

Cookies

O sušenkách jste určitě již slyšeli, minimálně v souvislosti s Evropskou Unií a její nechvalně proslulou cookie hláškou:

EU cookie hláška - Objektově orientované programování v JavaScriptu

Sušenky mají hned několik využití, nejdůležitější jsou 3:

  • Uložení dat v prohlížeči - Cookies byly dlouhou dobu jediným způsobem, jak si v prohlížeči něco uložit, aniž by se to při obnovení stránky ztratilo. Takto jsme si mohli uložit např., že jsme na stránce již vykřížkovali cookie hlášku ;-) K tomuto účelu se v dnešní době používá nové úložiště localStorage, viz dále. Tam se hodnoty z úložiště jednodušeji získávají a nezatěžují šířku pásma, protože se neposílají s každým požadavkem na server.
  • Přihlašování uživatelů - Jelikož prohlížeč spolu s požadavkem na server odesílá serveru i všechny cookies v dané relaci, realizuje se přes ně přihlášení uživatele na serveru. Jinými slovy, hodnotu cookies uživatele můžeme číst na serveru v jazycích jako je PHP nebo C# .NET. Toto využití je potom popsáno v příslušných serverových kurzech.
  • Získání informací o uživateli - Do cookies si Google ukládá, že jste na něm hledali boty. Google reklamy na jiných stránkách si poté načtou z cookies co vás zajímá a dané zboží vám nabízí. Podobně funguje i Google Analytics, jejichž cookie je snad na každé internetové stránce.

V klientském JavaScriptu tedy již pro používání cookies není příliš dobrý důvod, pro úplnost si práci s nimi ale stejně ukážeme, učit se ji nemusíte.

Cookie vytvoříme trochu podivným způsobem a to přiřazením do proměnné document.cookie, která obsahuje všechny cookies. Přiřazení do ní ovšem všechny cookies nepřepíše, ale přidá mezi ně novou. Aby podivnosti tohoto staršího API nekončily, vytváříme cookie jako řetězec 4 hodnot oddělených středníky, např. takto:

"eu_hlaska_zavrena=1; expires=Sun, 29 Mar 2020 22:00:00 GMT; path=/"

Cookie zadáváme:

  • Název a hodnotu
  • Datum expirace - Pokud vynecháme, cookie platí do zavření záložky prohlížeče. Pokud nastavíme do minulosti, cookie se ihned odstraní.
  • Cestu - Kde cookie platí, většinou nastavujeme na celou doménu hodnotou /.

Krkolomné vytváření cookie přímo svádí k napsání funkce. Její kód by byl následující:

function vytvorCookie(nazev, hodnota, expirace = null) {
    const castExpirace = expirace ? `expires=${expirace.toGMTString()};` : '';
    document.cookie = `${nazev}=${hodnota}; ${castExpirace} path=/`;
}

vytvorCookie('eu_hlaska_zavrena', 1, new Date(2020, 2, 30));

Ani načtení cookie není příliš intuitivní. Musíme si totiž prvně načíst všechny cookies v daném dokumentu, což je dlouhý textový řetězec, ve kterém jsou všechny cookies dané stránky oddělené středníky. Je tam pouze název a hodnota, datum expirace si vnitřně řeší prohlížeč.

Řetězec document.cookie vypadá např. takto:

_ga=GA1.2.1621812384.1525606041; __gads=ID=fdbec79e49891ee3:T=1525606041:S=ALNI_MYNHHGQJ65wZIjdzOc60pQanykM8w; __qca=P0-718587983-1559900791988; _gid=GA1.2.2042156113.1583272955; _gat=1; eu_hlaska_zavrena=1"

Nyní je na nás, abychom si z něj hodnotu eu_hlaska_zavrena vypreparovali. Samozřejmě musíme počítat i s tím, že daná cookie vůbec neexistuje! Funkce pro čtení cookies by vypadala takto:

function najdiCookie(nazev) {
    const cookies = document.cookie.split(';')
    for (const cookie of cookies) {
        hodnoty = cookie.split('=');
        if (nazev == hodnoty[0].trim())
            return hodnoty[1].trim();
    }
    return null;
}

document.write(najdiCookie('eu_hlaska_zavrena'));

Zkusme si v prohlížeči, že to opravdu funguje:

Tvoje stránka
localhost

Jak již bylo řečeno, všechny hodnoty všech cookie se odesílají na server v hlavičce HTTP požadavku při každém načtení každé stránky. Proto je používejte jen pokud nemůžete použít localStorage.

Cookie nastavená ze serveru může mít nastavenou vlastnost HttpOnly, čímž ji z klientského JavaScriptu nemůžeme načíst. Toto je základní bezpečnostní opatření, které by mělo být nastaveno při používání cookies k autentizaci uživatelů na serveru. Z klientského JavaScriptu tato vlastnost pochopitelně cookies nastavit nelze :)

Odstranění cookie je stejné jako její vytvoření, pouze nastavíme její expiraci do minulosti, což povede k jejímu odstranění. Jako hodnotu můžeme uvést cokoli.

IndexedDb

Posledním standardním úložištěm, které můžeme v JavaScriptu používat, je IndexedDB. Jak název napovídá, nejedná se již o pouhé úložiště, kam ukládáme data pod nějakými klíči, ale o plnohodnotnou databázi s tabulkami a indexy, z čehož také vznikl její název. Ukládáme tedy strukturovaná data. Databázové indexy nám umožňují v databázi vyhledávat řádově rychleji a jsme schopní s daty přímo pracovat, aniž bychom je museli převádět z/do string, jako je tomu u localStorage. Navíc podporuje transakce a další standardní databázové mechanismy, které nám zajistí datovou integritu (že data nejsou uložena špatně, třeba proto, že v aplikaci došlo k chybě, jednoduše se uloží buď vše nebo nic). V neposlední řadě podporuje rovněž ukládání souborů.

Databáze je tzv. NoSQL, to znamená, že s ní nekomunikujeme jazykem SQL, jako to u databází bývá zvykem, ale voláním metod na databázových objektech. To je někdy trochu krkolomné a proto pro ni vzniklo hned několik nástaveb.

IndexedDB je vhodná pro větší aplikace se složitější datovou strukturou a větším množstvím dat. Její používání převyšuje úroveň OOP kurzu a vydalo by na samostatný kurz, proto se s ní zde zabývat nebudeme.

IndexedDB bychom neměli zaměňovat s WebQL, což je jiná nestandardní databáze, která není podporována všemi prohlížeči.

V následujícím kvízu, Kvíz - Datové typy a datová úložiště v JavaScriptu, si vyzkoušíme nabyté zkušenosti z předchozích lekcí.


 

Předchozí článek
Řešené úlohy k 4.-5. lekci OOP v JavaScriptu
Všechny články v sekci
Objektově orientované programování v JavaScriptu
Přeskočit článek
(nedoporučujeme)
Kvíz - Datové typy a datová úložiště v JavaScriptu
Článek pro vás napsal David Hartinger
Avatar
Uživatelské hodnocení:
201 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity