nav_dugme codeBlog codeBlog
  • početna
  • Učionica
  • Saveti
  • Zanimljivosti
  • Kontakt

Lokalno skladištenje podataka browsera (sessionStorage, localStorage, cookies)

Viber
zoom_plus zoom_minus

Uvod

Nedugo posle početnog upoznavanja sa web dizajnom i bekend programiranjem, programeri se prirodno susretnu sa potrebom za lokalnim skladištenjem podataka koje browseri koriste. Od browsera očekujemo da "pamte" da smo prijavljeni na određeni sajt (da ne bismo morali ponovo da unosimo podatke za prijavu), prethodni sadržaj korpe pri online kupovini, boju pozadine i veličinu fonta koju smo izabrali i slično.

Ovakve stvari se svakako podrazumevaju (godinama unazad), ali - ne dešavaju se ipak "same od sebe".

Da bi sajtovi koje kreiramo imali opcije koje smo prethodno naveli (kao i druge, srodne opcije), moramo koristiti lokalna skladišta podataka.

Razlike između web kukija i lokalnog skladištenja

Verujemo da je našim čitaocima dobro poznat pojam HTTP kolačića ili kukija (engl. - cookie), kao metode za lokalno skladištenje podataka koje browser koristi. Kukiji jesu opšteprisutni i veoma korisni, ali, zahtevaju pažnju po pitanju pravilne implemetacije i (napomenimo takođe) nisu jedini način za lokalno skladištenje podataka.

Sam po sebi, kuki predstavlja nisku (string, tekstualni podatak) koja se kreira na serveru, šalje browseru i skladišti lokalno. U daljoj obradi podataka, kukiji postaju deo HTTP zahteva koji se šalju sajtu (prosto rečeno, svaki put kada se sajt obraća serveru, šalju se i kukiji koje je sajt prethodno od servera primio), tako da moramo voditi računa o njihovoj veličini (mada, budući da je maksimalna veličina jednog kukija 4KB, praktičnije je reći da moramo voditi računa o ukupnom broju kukija koje naš sajt koristi, jer veličina jednog kukija nije nešto što u današnje vreme predstavlja iole ozbiljniji problem).

Kukijima možemo pristupati preko serverskih jezika (kao što je PHP), dok, kada je u pitanju podrška za JavaScript, stvari funkcionišu malo drugačije: možemo kreirati kukije koji se mogu čitati samo na serveru (iz sigurnosnih razloga), kao i one kojima se može pristupati preko JavaScripta-a.

Međutim (kao što smo već spomenuli), ne moramo koristiti "uvek i samo" kukije za lokalno skladištenje podataka (pogotovo s obzirom na to što smo već naveli da se kukiji šalju serveru sa svakim HTTP zahtevom), već, pogotovo za "običnije" zahteve, možemo koristiti i lokalna skladišta koja su dostupna browserima.

U nastavku, upoznaćemo se sa načinima za pristup navedenim resursima (kukijima i lokalnim skladištima).

Operacije sa lokalnim skladištem preko JavaScript-a

Za sam početak, upoznaćemo se sa operacijama vezanim za skladištenje podataka browsera koje se obavlja "u lokalu" (preko frontend jezika).

JavaScript za ovu namenu koristi objekate sessionStorage i localStorage i, iako pomenuta dva objekta imaju mnogo sličnosti i gotovo identičnu sintaksu za pozivanje komandi, postoje razlike (i ralozi zašto ćemo u različitim okolnostima koristiti jednu ili drugu opciju):

  • sessionStorage - podaci su vezani za sesiju i brišu se pri zatvaranju browsera
  • localStorage - podaci ostaju trajno zapisani (odnosno, dok se ne obrišu ručno)

Objekat sessionStorage možemo koristiti za (recimo) pamćenje sadržaja tekstualnih pojla, u situacijama kada ne želimo da se posle osvežavanja stranice sadržaj izgubi, dok localStorage možemo koristiti za pamćenje večičina fonta, boja elemenata koje je korisnik izabrao (i tome slično).

Skladištenje podataka

Skladištenje podataka obavićemo pozivom komande setItem(), kojoj ćemo kao argmente predati ključ (identifikator preko koga ćemo nadalje obraćati podatku) i vrednost.

									
// Za upis u skladište koje je vezano za sesiju:

sessionStorage.setItem("boja_pozadine", "#2244ee");

// Za upis u lokalno skladište browsera:

localStorage.setItem("boja_pozadine", "#2244ee");
									
								
Slika 1. - Metoda setItem, za upis podatka u lokalna skladišta browsera.

Čitanje podataka

Za čitanje podatka koji smo već upisali, možemo koristiti funkciju getItem(), kojoj ćemo kao argument predati ključ nekog od podataka:

									
// Za čitanje podataka iz skladišta koje je vezano za sesiju:

var bojaPozadine = sessionStorage.getItem("boja_pozadine");

// Za čitanje podataka iz lokalnog skladišta browsera:

var bojPozadine = localStorage.getItem("boja_pozadine");

// U oba slučaja, promenljiva bojaPozadine
// dobija vrednost "#2244ee"
									
								
Slika 2. - Metoda getItem, za čitanje podataka iz lokalnih skladišta browsera.

Uklanjanje podataka

Za uklanjanje podataka, koristićemo funkciju removeItem() (uz predavanje ključa), ukoliko želimo da uklonimo određeni podatak, ili, clearAll(), ukoliko želimo da ukonimo sve podatke iz lokalnog skladišta.

									
// Za uklanjanje podataka iz skladišta koje je vezano za sesiju:

sessionStorage.removeItem("boja_pozadine");

// Za čitanje podataka iz lokalnog skladišta browsera:

localStorage.removeItem("boja_pozadine");

// U oba slučaja, podatak sa ključem
// bojaPozadine biće uklonjen.
// Ukoliko želimo da ispraznimo skladišta
// podataka u potpunosti, koristićemo sledeći kod:

sessionStorage.clearAll();

// ... ili ....

localStorage.clearAll();
									
								
Slika 3. - Metode removeItem i clearAll, za uklanjanje podataka iz lokalnih skladišta browsera.

Rad sa kukijima je nešto složeniji. Podaci smešteni u sessionStorage ističu po zatvaranju browsera, dok oni smešteni u localStorage ne ističu (dok se sami za to ne "pobrinemo") nikad. Kada su u pitanju kukiji, pored ključeva i vrednosti, možemo (ili, u određenim okolnostima, pogotovo kada nas na to navode sigurnosni razlozi - moramo), navesti i trenutak isteka, kao i to da li je u pitanju kuki koji se može čitati samo na serveru (a takođe i domen i putanju za koje kuki važi).

U nastavku, pozabavićemo se obradom kukija u PHP-u i JavaScript-u.

Operacije sa kukijima u PHP-u

PHP, kao serverski jezik, nudi dobru podršku za kukije i raspolaže svim neophodnim funkcijama za raspolaganje ovim resursima.

Krenimo redom ...

Kreiranje i ažuriranje kukija

Za kreiranje kukija preko PHP-a, koristićemo sledeći kod:

									
<?php
	setcookie(naziv, vrednost, trenutak_isteka, domen);
?>
									
								
Slika 4. - Funkcija setcookie, preko koje možemo kreirati kuki.

Da bismo bolje razumeli šta navedeni argumenti označavaju, pogledaćemo primer:

									
<?php
	$boja_pozadine = "#44ee11";

	setcookie("boja_pozadine", $boja_pozadine, time() + 86400 * 30, "/");

	// Ako želimo, možemo to uraditi i ovako:
	// 
	// $boja_pozadine = "#44ee11";
	// $naziv_kukija  = "boja_pozadine";
	// setcookie($naziv_kukija, $boja_pozadine, time() + 86400 * 30, "/");
	//
	// ARGUMENTI SU:
	//
	// naziv:            "boja_pozadine" - naziv po kome ćemo (nadalje)
	//                   prepoznavati dati kuki
	// vrednost:         $boja_pozadine - vrednost koju upisujemo u kuki
	//                   (najvažniji argument) biće vrednost promenljive
	//                   $boja_pozadine ("#44ee11")
	// trenutak_isteka:  time() + 86400 * 30 - označava trenutak u kome
	//                   kuki ističe i zadaje se u sekundama;
	//                   Preko funkcije time(), dobijamo broj sekundi po
	//                   UNIX Timestamp koji odgovara trenutnom vremenu,
	//                   dok je 86400 broj sekundi u jednom danu:
	//                   86400 = 24 * 60 * 60
	//                   .... što znači da naš kuki ističe za 30 dana
	//                   od trenutka kada pozivamo funkciju setcookie()
	// domen:            "/" - Ovim deklarišemo kuki koji će važiti za
	//                   ceo domen

?>
									
								
Slika 5. - Poziv funkcije setcookie, sa detaljnim opisom argumenata.

Za ažuriranje (u našem slučaju, ako korisnik promeni boju pozadine), jednostavno ćemo ponovo pozvati funkciju setcookie() i predati drugi vrednost:

									
<?php
	$boja_pozadine = "#332aff";

	setcookie("boja_pozadine", $boja_pozadine, time() + 86400 * 30, "/");

	// Sve je "isto", ali, ovoga puta predajemo vrednost:
	// "#332aff"
?>
									
								
Slika 6. - Ažuriranje kukija, koje se (takođe) obavlja pozivom funkcije setcookie, pri čemu se kao prvi argument predaje naziv već postojećeg kukija, a kao drugi, nova vrednost.

Sada je kuki dostupan širom domena (svim stranicama sajta) i možemmo mu lako pristupiti.

Pristup kukijima

Za pristup kukijima, koristićemo superglobalnu promenljivu $_COOKIE, sa odgovarajućim indeksima koji (kao što verovatno pretpostavljate) odgovaraju nazivima kukija koje smo zadavali kada smo pozivali funkciju setcookie().

Naravno, da bi sve imalo pravog smisla, pre nego što pristupimo kukiju, prvo ćemo proveriti da li dati kuki postoji, za šta ćemo koristiti do sada dobro poznatu funkciju isset():

									
<?php
	// Podrazumevana boja pozadine je bela:
	
	$boja_pozadine = "#fff";
	$poruka        = "";
	
	if(isset($_COOKIE['boja_pozadine']))
	{
		$boja_pozadine = $_COOKIE['boja_pozadine'];
	}
	
	echo "<font color='" . $boja_pozadine . "'>Ispis</font>";
?>
									
								
Slika 7. - Provera kukija preko funkcije isset i pristup vrednosti kukija preko superglobalne promenljive $_COOKIE.

Uklanjanje kukija

Kukiji se uklanjaju na jednostavan, ali pomalo idiosinkratičan, način - pozivanjem funkcije setcookie(), pri čemu se za trenutak_isteka zadaje trenutak u prošlosti:

									
<?php
	setcookie("boja_pozadine", "", 1, "/");

	// naziv:            "boja_pozadine" - Preko prvog argumenta,
	//                   određujemo  koji je kuki predviđen za brisanje
	// vrednost:         "" - Prilično je svejedno, ali, pri brisanju
	//                   kukija tipično se zadaje vrednost koja dodatno
	//                   sugeriše da je u pitanju uklanjanje
	// trenutak_isteka : 1 - UNIX Timestamp za 20.03.2021 u 10h
	//                   (vreme je ovaj članak kreiran), funkcija time()
	//                   vraća vrednost 1616230800, što veoma jasno
	//                   pokazuje da vrednost 1 označava
	//                   "trenutak u prošlosti"
?>
									
								
Slika 8. - Uklanjanje kukija, koje se obavlja kao ažuriranje, pri čemu se kao vreme isteka zadaje trenutak u prošlosti.

Za kraj, ostaje nam nešto što ćemo u praksi raditi na samom početku - da proverimo da li browser uopšte dozvoljava kreiranje kukija (ako se pitate zašto je ovo uopšte neophodno, podsetićemo vas da internet browseri omogućavaju automatsko brisanje kukija pri zatvaranju) ....

Provera da li browser podržava kukije

Iako PHP nema specijalizovanu funkciju za kreiranje kukija, proveru možemo jednostavno obaviti na sledeći način:

  • kreiraćemo kuki određenog naziva
  • proverićemo da li dati kuki postoji
									
<?php
	setcookie("proba", "proba kukija", time() + 3600, "/");

	if(isset($_COOKIE['proba']))
	{
		echo "Čuvanje kukija je omogućeno.";

		// U praksi, u slučaju da je čuvanje kukija omogućeno,
		// nećemo (nepotrebno) o tome obaveštavati korisnika
	}
	else
	{
		echo "Čuvanje kukija nije dozvoljeno!";

		// U praksi, u slučaju da je čuvanje kukija nije omogućeno,
		// moramo ipak naći elegantniji način da o tome
		// obavestimo korisnika
	}
?>
									
								
Slika 9. - Pomoćna skripta preko koje možemo proveriti da li je podrška za kukije u browseru uključena (provera koju moramo obaviti, budući da korisnik može isključiti pamćenje kukija u podešavanjima browsera).

Takođe, u prethodnoj skripti, možemo koristiti i drugačiji uslov ....

									
<?php
	
	// ....

	if(count($_COOKIE) > 0)
	
	// ....
?>
									
								
Slika 10. - Uslov iz prethoidne skripte (slika X), koji možemo zapisati na drugi način.

.... što navodimo (iako je prethodni kod zanimljiv sam po sebi), pre svega iz razloga što verujemo da će naši čitaoci naći bolje i kreativnije načine da iskoriste mogućnost prebrojavanja postojećih kukija.

Pošto smo se, kroz primere u PHP-u, upoznali sa opštim principima čuvanja i obrade kukija, pogledaćemo kako sve navedene operacije možemo koristiti u JavaScript-u.

Operacije sa kukijima u JavaScript-u

JavaScript kao skriptni jezik takođe nudi dobru podršku za rad sa kukijima, ali, mora se priznati da se oko nekih stvari ipak moramo malo više potruditi nego što je to slučaj sa PHP-om.

Najbolje je da to ipak shvatimo kao priliku da se dodatno upoznamo sa ovim jezikom i utvrdimo ono što smo do sada naučili (pogotovo kada je u pitanju rad sa nizovima).

Kreiranje kukija

Za kreiranje kukija preko JavaScript-a, pozivaćemo kod po sledećem obrascu:

									
document.cookie = "naziv=vrednost; expires=datum; path=/";
									
								
Slika 11. - Opšti oblik naredbe za kreiranje kukija u JS-u.

Iako je kod naizgled drugačiji, prepoznajemo princip sa kojim smo se upoznali u odeljku o kukijima u PHP-u: predajemo naziv kukija, vrednost, vreme isteka i domen.

Deluje jednostavno, međutim, kada je u pitanju unos datuma, potrebno je koristiti sledeći format zapisa ....

									
Thu, 01 Jan 1970 00:00:00 UTC
									
								
Slika 12. - Format zapisa vremena (UTC) koji moramo koristiti pri dodavanju kukija.

.... što ni iz daleka nije intuitivno.

Da bismo olakšali sebi posao dodavanja novog kukija, kreiraćemo pomoćnu funkciju koja će kreirati nisku za dodavanje kukija - onako kako to od nas zahteva jezik JavaScript:

									
function formatiranjeKukija(naziv, vrednost, dani, sati, domen) {
	
	let datum = new Date();
	
	datum.setTime(datum.getTime() + (dani * 86400 + sati * 3600) * 1000);

	return 	naziv + "=" + "vrednost; " +
	       "expires=" + datum.toUTCString() + 
	       ((domen != "")? "; path=" + domen : "");
	//*/
}
									
								
Slika 13. - Pomoćna metoda za dodavanje kukija, preko koje se niska za dodavanje formatira automatski.

Princip je skoro isti kao u prethodnom slučaju (kada smo koristili PHP):

  • objekat klase Date (datum) beleži datum
  • metoda getTime() upisuje trenutni datum u objekat datum
  • na vreme koje zada prethodna metoda dodaćemo:
    • dani * 86400 (broj dana * broj sekundi u jednom danu)
    • sati * 3600 (broj sati * broj sekundi u jednom satu)
  • zbir prethodne dve vrednosti pomnožićemo sa 1000, budući da metoda setTime() operiše sa milisekundama
  • preko metode toUTCString() kreiraćemo format koji je neophodno koristiti pri kreiranju kukija u JS-u

Ako sada pozovemo sledeći kod:

									
document.cookie = formatiranjeKukija("boja_pozadine", "#2244ee", 30, 0, "/");
									
								
Slika 14. - Poziv funkcije formatiranjeKukija, koju smo definisali u prethodnom koraku.

.... lako ćemo postaviti novi kuki.

Pristup kukijima

Ovo je (moramo priznati) najmanje jednostavan deo, kada su u pitanju kukiji u JavaSkript-u.

Za pristup kukijima, JS nam nudi samo da preuzmemo sve kukije, u obliku niske, preko sledećeg koda:

									
var kukiji = document.cookie;
									
								
Slika 15. - Prvi korak u pristupanju kukijima u JS-u je poziv koda sa slike ....

.... pri čemu ćemo samo dobiti nisku sledećeg formata:

									
"korisnik=darth_vader"; id=411; boja_pozadine=#2244ee"
									
								
Slika 16. - Kod sa prethodne slike (slika X) vratiće nam nisku koja sadrži sve podatke o svim kukijima (koje sajt koristi). Iako je očigledno da su svi podaci tu, jasno je i da moramo preduzeti dalje korake u obradi ovih podataka.

Međutim, budući da su delovi niske razdvojeni znakom tačka-zarez, lako ćemo datu nisku, preko komande split(), pretvoriti u niz čijim elementima možemo pristupati pojedinačno:

									
kukiji = kukiji.split(";");
									
								
Slika 17. - Za podelu niske koju vraća kod document.cookie, koristićemo komandu split(), pri čemu ćemo dobiti niz niski.

.... pri čemu promenljiva kukiji više nije obična niska, već (višedimenzionalni) niz sledećeg sadržaja:

									
[
	"korisnik=darth_vader",
    " id=411",
    " boja_pozadine=#2244ee"
]
									
								
Slika 18. - Primer niza niski koji ćemo dobiti korišćenjem komande split(), posle poziva naredbe document.cookie.

U pitanju je niz niski, u kome svaka pojedinačna niska sadrži dva podatka (naziv i vrednost), razdvojena znakom jednakosti.

Pri svakom obraćanju ovim pojedinačnim niskama možemo, ponovo preko komande split(), kreirati pomoćnu promenljivu red - niz koji sadrži naziv kukija i pripadajuću vrednost:

									
let red = kukiji[0].split("=");

// red  = ["korisnik", "darth_vader"];

red     = kukiji[1].split("=");

// red  = [" id", "411"];

red     = kukiji[2].split("=");

// red  = [" boja_pozadine", "#2244ee"];

									
								
Slika 19. - Ukoliko ponovo pozovemo komandu split(), pri čemu ćemo ovoga puta predati "=", kao argument za razdvajanje, dobićemo niz sa dva zasebna podatka, što je upravo ono što nam i treba.

Primećujemo da, u drugom i trećem nizu, prva niska sadrži razmak na početku, što je neizbežno, ali lako rešivo (u daljoj obradi) preko komande trim().

Pošto su nam poznati svi detalji, možemo napraviti jednostavnu funkciju koja će pronaći sadržaj određenog kukija (ili ustanoviti da traženi kuki ne postoji):

									
function pronalazenjeKukija(naziv) {
	let kukiji = document.cookie;
	kukiji = kukiji.split(";");

	// kukiji = [
	//              "naziv_1=vrednost_1",
	//              " naziv_2=vrednost_2",
	//              " naziv_3=vrednost_3",
	//              ....
	//              " naziv_n=vrednost_n",
	//          ];
		
	for (let i = 0; i < kukiji.length; i++) {
		
		// kukiji[i] = "naziv_i=vrednost_i";

		let red = kukiji[i].trim().split("=");

		// red = ["naziv_i", "vrednost_i"];
		
		if(red[0] == naziv) {
			return red[1];
		}
	}

	return false;
}
									
								
Slika 20. - Skripta za pronalaženje vrednosti kukija preko zadatog naziva.

Vama ostavljamo da gornju funkciju (koja je krajnje adekvatna za svakodnevnu upotrebu), dodatno optimizujete.

Uklanjanje kukija

Za uklanjanje kukija koristimo poznati princip: pozivamo metodu za dodavanje/ažuriranje kukija u kojoj kao poništavamo vrednost i takođe, kao vreme isteka, navodimo "trenutak u prošlosti".

Ovoga puta, kao "trenutak u prošlosti", sasvim dobro će poslužiti početak UTC epohe - 01.01.1970.

Ako pozovemo sledeći kod:

									
document.cookie = "boja_pozadine=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
									
								
Slika 21. - Uklanjanje kukija u JS-u obavlja se po već poznatom principu: pozivamo kod za ažuriranje, ukidamo vrednost i zadajemo trenutak u prošlosti kao vreme isteka.

.... kuki će biti uklonjen.

Provera da li browser podržava kukije

Kao što smo naveli u odeljku o kukijima u PHP-u, provera podržanosti kukija preko JavaScript-a je krajnje jednostavna:

									
if(navigator.cookieEnabled)
{
	alert("Čuvanje kukija je omogućeno.");

	// U praksi, u slučaju da je čuvanje kukija omogućeno,
	// nećemo (nepotrebno) o tome obaveštavati korisnika
}
else
{
	alert("Čuvanje kukija nije dozvoljeno!");

	// U praksi, u slučaju da je čuvanje kukija nije omogućeno,
	// naći ćemo elegantniji način da o tome obavestimo korisnika
}
									
								
Slika 22. - Preko JavaScript-a lako možemo proveriti da li je podrška za kukije u browseru uključena.

Naravno, i ovde ćemo poštovati primedbe koje smo naveli u komentarima (o tome da su kukiji podržani nećemo nepotrebno obaveštavati korisnike, a, u slučaju da kukiji nisu podržani, pronaći ćemo elegantniji način da korisnike obavestimo o tome).

Zaključak

Na kraju, pošto smo se upoznali sa mehanizmima za "trajno" čuvajne podataka iz browsera na računaru klijenta, možemo preći na sledeći (reklo bi se "prirodan") korak.

U pitanju je autentifikacija (čime smo se već, u velikoj meri, pozabavili u tutorijalu za kreiranje forme za prijavu) i autorizacija korisnika, što će biti tema narednog članka ....

Autor članka Nikola Vukićević Za web portal www.codeblog.rs
Napomena: Tekstovi, slike, web aplikacije i svi ostali sadržaji na sajtu www.codeblog.rs (osim u slučajevima gde je drugačije navedeno) predstavljaju intelektualnu svojinu autora sajta www.codeblog.rs i zabranjeno je njihovo korišćenje na drugim sajtovima i štampanim medijima, kao i bilo kakvo drugo korišćenje u komercijalne svrhe, bez eksplicitnog pismenog odobrenja autora.
©2021. Sva prava zadržana.
Viber
početna Početna > Članci > Lokalno skladištenje podataka browsera (sessionStorage, localStorage, cookies)

Info & povezani članci

Info

trejler_sat Datum objave: 23.03.2021.

trejler_dokument Jezici: PHP,
JavaScript

trejler_teg_narandzasti Težina: 6/10

PHP

Uvod u PHP PHP - Prosleđivanje podataka preko URL-a ($_GET) PHP - Prosleđivanje podataka preko HTML forme ($_POST) PHP - Direktno prosleđivanje podataka između stranica ($_SESSION) Ažuriranje praznih kolona u bazi podataka Kreiranje forme za prijavu korisnika

Povezani članci

Pokretanje lokalnog web servera Kako napraviti web sajt - 1. deo - Početni koraci Uvod u Javascript i DOM JSON - tekstualni format za predstavljanje objekata Struktura web adresa i pristup internet stranicama HTTP - Statusni kodovi Kako napraviti dobru lozinku Regularni izrazi - napredna pretraga teksta
Preuzmite PDF verziju
Simple things should be simple, complex things should be possible.
Alan Kay
codeBlog codeBlog
Projekat posvećen popularizaciji kulture i veštine programiranja među mladim programerima.
Napomena: Tekstovi i slike na sajtu www.codeblog.rs (osim u slučajevima, gde je drugačije navedeno) predstavljaju intelektualnu svojinu autora sajta www.codeblog.rs i zabranjeno je njihovo korišćenje na drugim sajtovima i štampanim medijima, kao i bilo kakvo drugo korišćenje u komercijalne svrhe, bez eksplicitnog odobrenja autora.
© 2021. Sva prava zadržana.
Facebook - logo
Instagram - logo
LinkedIn - logo
Twitter - logo
E-mail
Naslovna
   •
Uslovi korišćenja
   •
Obaveštenja
   •
FAQ
   •
Kontakt