6. diel - Dátové úložiská v JavaScripte
V predchádzajúcom cvičení, Riešené úlohy k 4.-5. lekciu OOP v JavaScripte, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.
V dnešnej lekcii si predstavíme akými spôsobmi môžeme v JavaScripte ukladať dáta tak, aby sme ich pri obnovení stránky hneď zas nestratili.
Web storage
Web storage čiže DOM Storage je súhrnný názov pre úložisko
localStorage
a sessionStorage
.
localStorage
localStorage
je úložisko v internetovom prehliadači
používateľa (preto local), do ktorého sa môžu ukladať dáta v
textovom reťazci, ku ktorým môžeme neskôr pristupovať. K
dispozícii máme pre našu aplikáciu 10MB priestoru, čo je pre texty naozaj
veľa:) Možnosť ukladať len text je pomerne obmedzujúce, ale rovnako je
localStorage
kvôli svojej jednoduchosti najobľúbenejším
úložiskom dát, o ktoré nechceme po obnovení alebo zatvorení stránky
prísť.
Práca s localStorage
S localStorage
sa pracuje veľmi jednoducho.
setItem()
Na uloženie nejakého reťazca pod textový index použijeme metódu
setItem()
. Skúsme si pod kľúč "jmeno"
uložiť
string "Karel"
:
localStorage.setItem("jmeno", "Karel");
Stránku sa skriptom otvoríme v prehliadači, kód následne zmažeme a stránku zas obnovíme. Tým sme si istí, že Karla už nikde v kóde nemáme, ale je uložený v úložisku.
getItem()
Analogicky pre prečítanie hodnoty pod kľúčom použijeme
getItem()
. Teraz si vypíšeme čo je pod kľúčom
"jmeno"
, čím získame hodnotu "Karel"
:
document.print(localStorage.getItem("jmeno"));
výsledok:
Vidíme, že sa Karol naozaj načítal.
removeItem()
Asi vás neprekvapí, že reťazec pod nejakým kľúčom môžeme z
úložiska aj vymazať. Urobíme to metódou removeItem()
:
localStorage.removeItem("jmeno");
clear()
Úložisko môžeme kompletne vyprázdniť od všetkých kľúčov a dát pod
nimi metódou clear()
.
length
Počet položiek v localStorage
získame pomocou vlastnosti
length
:
document.write("Uloženo " + localStorage.length + " položek");
výsledok:
key()
Možno vás napadlo, ako zistíme, čo všetko je v localStorage
uložené alebo ako s položkami v úložisku pracovať hromadne. Posledný
chýbajúci metóda je preto key(n)
, kde n
je index -
poradové číslo kľúča, ktorý chceme vrátiť. V kombinácii s vlastnosťou
length
tak dokážeme napr. Vypísať všetky kľúče v úložisku
a hodnoty pod nimi uložené. Urobme si posledný ukážku, čím naozaj
vyčerpáme možnosti, ktoré localStorage
ponúka:
for (let i = 0; i < localStorage.length; i++) { const klic = localStorage.key(i); document.write(klic + ": " + localStorage.getItem(klic) + "<br>"); }
výsledok:
Kód uloží do localStorage
3 hodnoty pod 3 kľúče a
následne vypíše počet položiek v úložisku.
Poradie kľúčov môže byť v každom prehliadači inej a
preto by na ňom naše aplikácie nemala závisieť. Nemali by sme teda napr.
Predpokladať, že prvýkrát pridaná hodnota bude vždy pod kľúčom
0
.
Uloženie viac hodnôt pod jeden kľúč
Možno premýšľate, akým spôsobom je možné uložiť napr. Pole hodnôt alebo objekt pod jeden kľúč úložiska? Ak by sme súvisiace hodnoty neseskupovali pod jeden kľúč, bol by v úložisku naozaj neporiadok, len si skúste predstaviť, ako by sme tam uložili 2 používateľa. Preto si celý objekt prevedieme na text, čo sa v JavaScripte robí pomocou formátu JSON. To sa naučíme hneď v nasledujúcej lekcii a potom si to aj prakticky vyskúšame na našom OOP diári.
sessionStorage
Okrem localStorage
existuje aj úložisko
sessionStorage
. To funguje úplne rovnako, ale líšia sa v
kontexte, v ktorej sú dáta uložené. Rozdiely sú 3:
- Dáta v
sessionStorage
sú unikátne pre každú záložku prehliadača. Keď si naopak otvoríme tú istú stránku používajúcelocalStorage
vo viacerých záložkách, budú všetky záložky používať to isté úložisko s tými rovnakými dátami. - Dáta budú stratená vo chvíli zatvorenie záložky.
Naopak dáta v
localStorage
v prehliadači zostávajú. - Hovoríte si prečo teda
sessionStorage
používať, keď sa so zatvorením stránky rovnako zmaže? To už by sme predsa mohli dáta uložiť len do premenných ako doteraz ...sessionStorage
podobne ako cookies zostáva nedotknuté pri obnovení stránky alebo pri prechode na inú stránku v tej istej doméne.
Cookies
O sušienkach ste určite už počuli, minimálne v súvislosti s Európskou Úniou a jej neslávne známu cookie hláškou:
Sušienky majú hneď niekoľko využitie, najdôležitejšie sú 3:
- Uloženie dát v prehliadači - Cookies boli dlhú dobu
jediným spôsobom, ako si v prehliadači niečo uložiť, bez toho aby sa to
pri obnovení stránky stratilo. Takto sme si mohli uložiť napr., Že sme na
stránke už vykřížkovali cookie hlášku;-) Na tento účel sa v dnešnej
dobe používa nové úložisko
localStorage
, viď ďalej. Tam sa hodnoty z úložiska jednoduchšie získavajú a nezaťažujú šírku pásma, pretože sa neposielajú s každým požiadavkou na server. - Prihlasovanie užívateľov - Keďže prehliadač spolu s požiadavkou na server odosiela serveri aj všetky cookies v danej relácii, realizuje sa cez ne prihlásenie používateľa na serveri. Inými slovami, hodnotu cookies používateľa môžeme čítať na serveri v jazykoch ako je PHP alebo C # .NET. Toto využitie je potom popísané v príslušných serverových kurzoch.
- Získanie informácií o používateľovi - Do cookies si Google ukladá, že ste na ňom hľadali topánky. Google reklamy na iných stránkach si potom načítajú z cookies čo vás zaujíma a daný tovar vám ponúka. Podobne funguje aj Google Analytics, ktorých cookie je snáď na každej internetovej stránke.
V klientskom JavaScriptu teda už pre používanie cookies nie je príliš dobrý dôvod, pre úplnosť si prácu s nimi ale rovnako ukážeme, učiť sa ju nemusíte.
Vytvorenie novej cookie
Cookie vytvoríme trochu podivným spôsobom a to priradením do premennej
document.cookie
, ktorá obsahuje všetky cookies. Priradenie do nej
však všetky cookies neprepíše, ale pridá medzi nich novou. Aby podivnosti
tohto staršieho API nekončili, vytvárame cookie ako reťazec 4 hodnôt
oddelených bodkočiarkami, napr. Takto:
"eu_hlaska_zavrena=1; expires=Sun, 29 Mar 2020 22:00:00 GMT; path=/"
Cookie zadávame:
- Názov a hodnotu
- Dátum expirácie - Ak vynecháme, cookie platí do zatvorenie záložky prehliadača. Ak nastavíme do minulosti, cookie sa ihneď odstráni.
- Cestu - Kde cookie platí, väčšinou nastavujeme na celú
doménu hodnotou
/
.
Krkolomné vytváranie cookie priamo zvádza k napísaniu funkcie. Jej kód by bol nasledujúci:
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));
Načítanie hodnoty cookie
Ani načítanie cookie nie je príliš intuitívne. Musíme si totiž prvýkrát načítať všetky cookies v danom dokumente, čo je dlhý textový reťazec, v ktorom sú všetky cookies danej stránky oddelené bodkočiarkami. Je tam len názov a hodnota, dátum expirácie si vnútorne rieši prehliadač.
Reťazec document.cookie
vyzerá napr. 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"
Teraz je na nás, aby sme si z neho hodnotu eu_hlaska_zavrena
vypreparoval. Samozrejme musíme počítať aj s tým, že daná cookie vôbec
neexistuje! Funkcie pre čítanie cookies by vyzerala 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'));
Skúsme si v prehliadači, že to naozaj funguje:
Ako už bolo povedané, všetky hodnoty všetkých cookie sa
odosielajú na server v hlavičke HTTP požiadavky pri každom načítaní
každej stránky. Preto je používajte len ak nemôžete použiť
localStorage
.
Cookie nastavená zo servera môže mať nastavenú
vlastnosť HttpOnly
, čím ju z klientskeho JavaScriptu nemôžeme
načítať. Toto je základné bezpečnostné opatrenia, ktoré by malo byť
nastavené pri používanie cookies k autentifikáciu používateľov na
serveri. Z klientskeho JavaScriptu táto vlastnosť pochopiteľne cookies
nastaviť nedá:)
Odstránenie cookie
Odstránenie cookie je rovnaké ako jej vytvorenie, iba nastavíme jej expirácii do minulosti, čo povedie k jej odstráneniu. Ako hodnotu môžeme uviesť čokoľvek.
IndexedDB
Posledným štandardným úložiskom, ktoré môžeme v JavaScripte
používať, je IndexedDB. Ako názov napovedá, nejedná sa už o obyčajné
úložisko, kam ukladáme dáta pod nejakými kľúčmi, ale o plnohodnotnú
databázu s tabuľkami a indexy, z čoho tiež vznikol jej názov. Ukladáme
teda štruktúrované dáta. Databázové indexy nám umožňujú v databáze
vyhľadávať rádovo rýchlejšie a sme schopní s dátami priamo pracovať,
bez toho aby sme ich museli prevádzať z / do string, ako je tomu u
localStorage
. Navyše podporuje transakcie a ďalšie štandardné
databázové mechanizmy, ktoré nám zaistí dátovú integritu (že dáta nie
sú uložené zle, napríklad preto, že v aplikácii došlo k chybe, jednoducho
sa uloží buď všetko alebo nič). V neposlednom rade podporuje tiež
ukladanie súborov.
Databáza je tzv. NoSQL, to znamená, že s ňou nekomunikujeme jazykom SQL, ako to u databáz býva zvykom, ale volaním metód na databázových objektoch. To je niekedy trochu krkolomné a preto pre ňu vzniklo hneď niekoľko nadstavieb.
IndexedDB je vhodná pre väčšie aplikácie sa zložitejšie dátovou štruktúrou a väčším množstvom dát. Jej používanie prevyšuje úroveň OOP kurzu a vydalo by na samostatný kurz, preto sa s ňou tu zaoberať nebudeme.
IndexedDB by sme nemali zamieňať s WebQL, čo je iná neštandardné databázy, ktorá nie je podporovaná všetkými prehliadačmi.