nav_dugme codeBlog codeBlog
  • početna Početna stranica
  • Sačuvani članci Sačuvani članci
  • Učionica
  • Saveti
  • Zanimljivosti
  • Kontakt

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

Viber
zoom_plus zoom_minus bookmark

Uvod

Nedugo posle početnog upoznavanja sa web dizajnom i backend programiranjem, programeri se prirodno susretnu sa potrebom za lokalnim skladištenjem podataka koje browseri koriste za prikaz sajtova.

Od browsera se očekuje da "upamte" da je korisnik prijavljen na određeni sajt, da sačuvaju prethodni sadržaj korpe pri online kupovini, boju pozadine i veličinu fonta koju je korisnik izabrao, kao i mnogo šta još.

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

Da bi sajtovi koje kreiramo mogli da koriste opcije koje smo prethodno naveli (kao i druge srodne opcije), potrebno je da im omogućimo da podatke smeštaju na računarima klijenta, preko kukija i lokalnih skladišta podataka.

Razlike između HTTP kukija i lokalnog skladištenja

Verujemo da je čitaocima pojam HTTP "kolačića" ili kukija (engl. - cookie) dobro poznat iz svakodnevne prakse i u pitanju je način za lokalno skladištenje podataka koje posećeni sajtovi čuvaju za svoje potrebe.

Sam po sebi, kuki predstavlja nisku (string, tekstualni podatak) koja se kreira na serveru, šalje browseru i skladišti lokalno, međutim, u daljoj obradi podataka, kuki postaje deo HTTP zahteva koji se šalju serveru (prosto rečeno, svaki put kada se sajt obraća serveru, šalju se i kukiji koje je sajt prethodno od servera primio).

Iako su (u očima mnogih pojedinaca) kukiji sinonim za lokalno skladištenje podataka o sajtovima u opštem smislu, vidimo da postoji komunikacija sa serverom, videćemo i da procedura čitanja i zapisa kukija nije skroz trivijalna, tako da - kada se sve uzme u obzir - rad sa kukijima već na prvi pogled deluje relativno "zvanično".

Za "običnije" zahteve - možemo koristiti lokalna skladišta browsera kojima se može pristupiti preko Javascript-a (pri čemu nema komunikacije sa serverom).

Pri dizajniranju sajta, potrebno je voditi računa o veličini kukija koji se šalju, mada, budući da je maksimalna dozvoljena veličina pojedinačnog kukija 4KB, praktičnije je reći da moramo voditi računa o ukupnom broju kukija koje 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), ali i preko Javascript-a (sa čime ćemo se upoznati u nastavku).

Operacije sa lokalnim skladištem browsera preko Javascript-a

Za sam početak, upoznaćemo se sa korišćenjem lokalnih skladišta na računaru klijenta, za šta se u Javascript-u koriste objekti sessionStorage i localStorage.

Pomenuta dva objekta imaju mnogo sličnosti i gotovo identičnu sintaksu za pozivanje komandi, ali naravno postoje razlike (i razlozi 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 polja u situacijama kada ne želimo da se posle osvežavanja stranice sadržaj izgubi, dok localStorage možemo koristiti za pamćenje veličina fonta, boja elemenata koje je korisnik izabrao (i slično).

Skladištenje podataka

Skladištenje (upis) podataka obavlja se pozivom komande setItem, kojoj se kao argumenti predaju 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 je već upisan, koristi se funkcija getItem, kojoj se kao argument predaje 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 se funkcija removeItem (uz predavanje ključa) - ukoliko želimo da uklonimo određeni (pojedinačni) 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.

Podaci smešteni u sessionStorage ističu po zatvaranju browsera, dok oni smešteni u localStorage (osim ako se sami za to ne "pobrinemo") ne ističu nikad.

Rad sa kukijima je nešto složeniji.

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 navodimo 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 manipulaciju ovim resursima.

Krenimo redom ...

Kreiranje i ažuriranje kukija

Za kreiranje kukija preko PHP-a, koristi se funkcija setcookie:

		
<?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 (objašnjenja u komentarima):

		
<?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 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:            "/" - Ovako deklarisan kuki važiti za ceo domen
	//

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

Za ažuriranje kukija (na primer, ako korisnik promeni boju pozadine), jednostavno ćemo ponovo pozvati funkciju setcookie i predati druge vrednosti:

		
<?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žemo 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 treba proveriti da li kuki (uopšte) postoji, za šta možemo koristiti sada već 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), koji smo dobili
    //                   preko funkcije time(), ima vrednost 1616230800,
	//                   što veoma jasno pokazuje da timestamp sa
	//                   vrednošću 1 označava "trenutak u prošlosti"
	//
	// domen:            Kuki važi za ceo domen

?>
		
	
Slika 8. - Uklanjanje kukija, koje se obavlja kao ažuriranje, pri čemu se kao vreme isteka zadaje trenutak u prošlosti.

Za kraj, ostaje 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 ovakva provera uopšte neophodna, podsetićemo vas da internet browseri omogućavaju automatsko brisanje kukija pri zatvaranju, kao i to da se podrška za kukije doslovno isključi.

Provera podržanosti kukija u browseru

Iako PHP nema specijalizovanu funkciju za proveru podržanosti kukija u browseru, provera se može jednostavno obaviti u dva koraka:

  • pokušajem kreiranja kukija određenog naziva
  • naknadnom proverom da li kuki iz prethodnog koraka 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 9), koji možemo zapisati na drugi način.

.... što navodimo (iako je prvi kod više nego adekvatan), 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 obavljati u Javascript-u.

Operacije sa kukijima u Javascript-u

Javascript kao front-end 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 ipak da to shvatimo kao priliku da se dodatno upoznamo sa Javascript-om 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, a 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.

.... novi kuki će biti postavljen.

Pristup kukijima

Pristup kukijima je (reklo bi se) najmanje jednostavna operacija kada su u pitanju kukiji u Javascript-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 se (shodno primerima koje smo koristili) dobija niska sledećeg formata:

		
"korisnik=darth_vader"; id=411; boja_pozadine=#2244ee"
		
	
Slika 16. - Kod sa prethodne slike (slika 15) vratiće nisku koja sadrži sve podatke o svim kukijima (koje sajt koristi).

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

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

.... posle čega promenljiva kukiji više nije obična niska, već niz sledećeg sadržaja:

		
[
	"korisnik=darth_vader",
    " id=411",
    " boja_pozadine=#2244ee"
]
		
	
Slika 18. - Primer niza niski koji se dobija 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), koji su razdvojeni znakom jednakosti.

Pri svakom obraćanju "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 nisku "=" 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 i 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.

Čitaocima ostavljamo da gornju funkciju (koja je krajnje adekvatna za svakodnevnu upotrebu), dodatno optimizuju.

Uklanjanje kukija

Za uklanjanje kukija koristi se poznati (pomalo čudni) princip: pozivamo metodu za dodavanje/ažuriranje kukija u kojoj 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

Za razliku od prethodnih operacija, 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.

Sledeći koraci ....

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, to jest, primer koji se tipično vezuje za upotrebu lokalnih skladišta browsera.

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 jednog od narednih članaka ....

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.
© 2020-2023. Sva prava zadržana.
Viber
početna Početna > Članci > Lokalno skladištenje podataka browsera (sessionStorage, localStorage, cookies)

Info & povezani članci Info o članku - dugme

Info

trejler_sat Datum objave: 23.03.2021.

trejler_sat Poslednja izmena: ----

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 Uvod u web dizajn - 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 Ostali članci
Simplicity is the soul of efficiency.
Austin Freeman
codeBlog codeBlog
Projekat posvećen popularizaciji kulture i veštine programiranja.
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.
© 2020-2023. Sva prava zadržana.
Facebook - logo
Instagram - logo
LinkedIn - logo
Twitter - logo
E-mail
Naslovna
   •
Uslovi korišćenja
   •
Obaveštenja
   •
FAQ
   •
Kontakt