Browser Storage pentru aplicații HTML5

De ani de zile, unul dintre principalele avantaje ale scrisului de aplicații desktop a fost accesul facil la spațiul de stocare local pe mașina client. Dezvoltatorii de site-uri Web s-au confruntat cu incapacitatea de a stoca și de a prelua date de la mașina clientului pentru o perioadă lungă de timp, dar se pare că s-ar putea schimba în curând. S-ar putea chiar să credeți că are deja după ce ați citit acest articol. Da, voi discuta despre originea datelor persistente pe mașinile clienților și apoi vă voi prezenta standardul Web Storage.

Majoritatea dezvoltatorilor web știu că singurul tip de stocare locală pe care ne-am putea aștepta de la un browser web este sub formă de cookie-uri. Ei bine, nu în întregime. Dorința de a stoca date pe mașina client nu este un concept nou și nu a fost concepută în timp ce se creează specificații HTML5. Ceea ce este și mai surprinzător este faptul că o implementare de lucru a fost dezvoltată de Microsoft ca parte a setului de caracteristici IE6. L-au sunat datele utilizatorului și garantează în esență cel puțin 640KB de spațiu local pe domeniu, în funcție de politicile de securitate IE stabilite de utilizator. Acest lucru poate părea ca un spațiu foarte mic de standardul de astăzi, dar când îl comparăm cu spațiul maxim de 4KB disponibil pentru noi de către modulele cookie, îmbunătățirea este apreciabilă.

Ce este greșit cu cookie-urile?

O serie de lucruri. Cea mai importantă problemă cu cookie-urile este că acestea sunt trimise înainte și înapoi între browser și server cu fiecare cerere HTTP. Acest lucru nu este un comportament dorit, deoarece dezvoltatorii de multe ori nu doresc să transmită date locale pe server de mai multe ori, dacă o dată. Cookie-urile dau dezvoltatorului nicio alegere.

După cum am spus anterior, cookie-urile pot stoca numai până la 4KB de date. Nu este o mulțime de date, cu toate acestea 4KB sunt date suficiente pentru a încetini semnificativ cererile de pagină.

De asemenea, cookie-urile sunt transmise între client și server în text clar. Prin urmare, singura modalitate de a le proteja este prin criptarea datelor în timp ce comunicați cu serverul backend folosind SSL (Secure Socket Layer). Cu toate acestea, majoritatea site-urilor de pe Internet nu utilizează SSL, ceea ce lasă spațiul de stocare deschis pentru interceptarea.

Există și alte probleme care fac cookie-urile mai puțin utile. În mod ideal, dezvoltatorii doresc să aibă capacitatea de a persista cantități mari de date pe mașina client și nu trebuie să le transmită serverului de mai multe ori.

Care sunt soluțiile alternative??

Până în prezent nu am discutat soluții non-standard pentru datele persistente ale mașinii client. Când dezvoltatorii Adobe (cunoscuți apoi sub numele de Macromedia) au lansat Flash Player 6, aceștia au trebuit să abordeze aceeași problemă. În 2002, Flash Player 6 a introdus o nouă caracteristică denumită Obiect local comun sau mai des cunoscut sub numele de Flash cookie-uri pentru a introduce în mod eficient aceleași capabilități ca și modulele HTTP standard pentru fișierele și site-urile Flash. Obiectul local comun permite dezvoltatorilor să persiste până la 100 KB de date pe mașina client în mod prestabilit.

A doua soluție este implementarea de către Google a spațiului de stocare local, ca parte a pluginului Gears pentru browserele web. Gears a fost (și vă spun de ce folosesc a fost într-un moment) combinația de mai multe caracteristici lipsă și utile necesare pentru dezvoltarea aplicațiilor Rich Internet (RIA). Gears Storage Local a fost bazată pe specificațiile Web SQL mai puțin populare care au profitat de SQLite. Ați ghicit-o corect, Gears le-a dat dezvoltatorilor o bază de date SQL plină de suflare pentru a persista o cantitate nelimitată de date pe mașina client.

Dezvoltatorii Sistemului de stocare masivă Ajax (AMASS) au profitat de această ocazie și au dezvoltat o bibliotecă JavaScript a treia parte care a făcut posibil ca site-urile HTML standard să profite de caracteristica Local Shared Object din Flash sau pluginul Gears pentru a persista date despre client client. De asemenea, Biblioteca JavaScript Dojo este capabilă să detecteze disponibilitatea mecanismelor locale de stocare (de exemplu, Google Gears, obiecte comune partajate etc.) și oferă o interfață unificată pentru datele persistente în diferite browsere web.

Înapoi la motivul pentru care i-am spus că Gears a fost "în loc de" este încă ": asta pentru că Google a anunțat recent că va renunța la dezvoltarea suplimentară a pluginului Gears în favoarea HTML5 și a specificației Storage Web prezentate în acest tutorial.

Specificațiile HTML5 și Web Storage

Acum că lecția de istorie sa terminat, vom învăța despre Web Storage și vom arunca cu grijă în unele coduri pentru ao înțelege mai bine. Cea mai ușoară modalitate de a descrie stocarea pe Web este capacitatea de a persista datele de pe mașina client în forma unei singure taste pentru o singură valoare. Acest lucru este foarte similar cu modul în care sunt utilizate rețelele asociative:

 "Cheia": "Valoarea"

Stocarea locală este proiectată pentru a fi suportată în mod natural de browserele Web. Aceasta înseamnă că nu mai există biblioteci de la terțe părți și nu ești de acord cu Flash. Surprinzător, Web Storage a fost una dintre cele mai reușite specificații în ceea ce privește adoptarea de către browserele moderne. De fapt, aproape toate browserele moderne suport Web Storage, incluzând:

  • Internet Explorer 8+
  • Firefox 3.5+
  • Safari 4+
  • Opera 10.5+
  • iPhone Safari
  • Browser Web Android

În timp ce Web Storage își propune să furnizeze funcții similare cookie-urilor, a fost rafinat în continuare să nu poarte niciun atribut negativ. Spre exemplu, Web Storage permite persistența a până la 5MB de date, o creștere semnificativă a spațiului în comparație cu cât de mult pot fi stocate într-un Cookie. De asemenea, datele persistente utilizând Web Storage nu vor duce la trimiterea acelor date către backend-ul serverului cu fiecare solicitare de pagină. Acest lucru crește semnificativ performanța. Conform specificației Web Storage, numai browser-ele Web expiră datele persistente de la mașina locală atunci când sunt solicitate de către utilizator și vor evita întotdeauna ștergerea datelor în timp ce un script care ar putea accesa acele date se execută.

Browserele Web expun Web Storage prin localStorage obiect în JavaScript. O modalitate ușoară de a determina dacă un browser web poate suporta Web Storage este să execute acest cod JavaScript:

 var webStorageSupported = ('localStorage' în fereastră) && fereastră ['localStorage']! == null;

În conformitate cu specificația W3C pentru Web Storage, localStorage obiect implementează următorul set de metode și proprietăți din interfața de stocare. Să examinăm fiecare dintre aceste metode și proprietăți pentru a afla ce fac și cum pot fi utilizate:

 interfață de stocare readonly lung lungime; vid setItem (chei de șir, date obiect); Obiect getItem (Cheie cu șir); vid removeItem (tasta String); vid clar(); Şir cheie (indice lung); ; 

lungime proprietatea este foarte utilă. Acesta va returna numărul de perechi cheie / valoare salvate în prezent în Stocare locală sub domeniul accesat în prezent:

 alert (localStorage.length);

Dacă nu au fost salvate anterior perechi cheie / valoare în spațiul de stocare local, atunci scriptul de mai sus va afișa o fereastră de avertizare cu mesajul "0", în caz contrar mesajul va fi numărul de perechi chei / valori persistente.

setItem (cheie, valoare) metoda salvează pur și simplu o intrare nouă pe mașina locală. Pentru a salva cheia Nume cu valoarea arman am putea executa acest script:

 localStorage.setItem ("nume", "arman");

Pentru a vă asigura că cheia Nume a fost salvat într-adevăr la stocarea locală cu valoarea arman trebuie să folosim getItem (cheie) metodă. getItem metoda acceptă pur și simplu o cheie și caută spațiul de stocare local pentru a găsi o cheie de potrivire și apoi returnează valoarea acesteia.

 localStorage.setItem ("nume", "arman"); var valoare = localStorage.getItem ("nume"); alert (valoare);

Dacă executați scriptul de mai sus, ar trebui să vedeți o fereastră de avertizare care conține cuvântul arman apare pe ecran, confirmând că am salvat cu succes o pereche nouă de chei / valoare în spațiul de stocare local. Din moment ce localStorage obiectul se comportă similar cu array-urile asociative, am putea simplifica scriptul de mai sus pentru a arăta astfel și va funcționa în continuare la fel:

 localStorage ['nume'] = 'arman'; var valoare = localStorage ['nume']; alert (valoare);

Să ne uităm la removeItem (cheie) metodă. Această metodă este concepută pentru a elimina o pereche cheie / valoare salvată anterior din spațiul de stocare local. Dacă cheia nu există, această metodă nu face nimic. Următoarea eșantion de cod demonstrează utilizarea funcției removeItem metodă:

 localStorage.setItem ("nume", "arman"); localStorage.removeItem ( 'name'); var valoare = localStorage.getItem ("nume"); alert (valoare);

Când scriptul de mai sus este executat, ar trebui să vedeți o fereastră de alertă cu valoarea nul în caseta de alertă. Utilizarea Nume cheie, scriptul de mai sus creează pur și simplu o pereche nouă de chei / valoare și o elimină imediat din spațiul de stocare local. Ulterior, o valoare nulă este returnată atunci când accesați stocarea locală cu aceeași valoare Nume cheie.

Vor veni ocazii în care va exista nevoia de a curăța complet stocarea locală și de a începe cu o ardezie curată. clar() metoda este proiectată exact în acest scop. Această metodă golește automat toate perechile cheie / valoare salvate anterior din spațiul de stocare local. Dacă nu există înregistrări, nimic nu se va schimba.

 localStorage.setItem ("nume", "arman"); localStorage.setItem ("nume", "smith"); localStorage.setItem ("nume", "franc"); alert (localStorage.length); localStorage.clear (); alert (localStorage.length);

Deși scriptul de mai sus creează trei perechi noi de chei / valoare (după cum reiese din prima alertă), apelul la metoda clear () elimină toate intrările. Ulterior, a doua fereastră de alertă va afișa un mesaj "0".

Metoda finală la care trebuie să ne uităm este cheie (index) metodă. Această metodă va prelua numele unei chei pe baza parametrului index. localStorage menține o listă bazată pe 0 a tuturor intrărilor în sine. Prin urmare, pentru a accesa prima cheie din spațiul de stocare local, trebuie să folosim 0 ca index, așa cum este ilustrat în acest script:

 localStorage.clear (); localStorage.setItem ("vârstă", 5 ani); alert (localStorage.key (0));

Când scriptul de mai sus este executat, ar trebui să afișeze o fereastră de avertizare cu mesajul "vârstă". Rețineți cum în exemplul de mai sus primul rând de cod șterge spațiul de stocare local. Aceasta este pentru a ne asigura că începem cu o ardezie curată. O altă aplicație utilă a cheie() metoda este în legătură cu lungime proprietate. De exemplu, pentru a obține toate perechile cheie / valoare din spațiul de stocare local fără a cunoaște în prealabil cheile, am putea scrie un script după cum urmează:

 localStorage.clear (); localStorage.setItem ("titlu", "domnul"); localStorage.setItem ("nume complet", "Aaron Darwin"); localStorage.setItem ("vârstă", 17); localStorage.setItem ("înălțime", 182,5); pentru (var i = 0; i < localStorage.length; i++)  var keyName = localStorage.key(i); var value = localStorage.getItem(keyName); alert(keyName + " = " + value); 

În scriptul de mai sus, codul nostru se șterge mai întâi și apoi adaugă patru perechi cheie / valoare în memoria locală. Apoi utilizează lungime proprietate într-o Pentru pentru a determina cheia pentru fiecare pereche cheie / valoare. La fiecare iterație a buclă, cheia este atribuită funcției KeyName variabilă care este apoi trecută la getItem () pentru a-și recupera valoarea.

Subtilitățile

Când accesați date utilizând o cheie care nu există în spațiul de stocare local, în loc de o excepție, a nul valoarea este întotdeauna returnată. Acest lucru face dificilă cunoașterea valorii cheii nul sau cheia pur și simplu nu există în depozitul local.

Cel de-al doilea, despre care să vorbim, este setItem (cheie, valoare) metodă. Știm că putem transfera orice tip de valoare către setItem () metoda pentru valoare parametru, dar acest lucru nu este complet adevărat. În JavaScript, putem crea Imagine obiecte. Cu toate acestea, implementarea actuală a Web Storage permite numai tipuri primitive persistente, cum ar fi Şir, boolean, Întreg și Pluti tipuri. Prin urmare, ne putem aștepta ca următorul script să arunce o excepție și să se prăbușească:

 var imageObject = imagine nouă ("http://www.google.com/logo.gif"); localStorage.setItem ("imagine", imagineObject);

În plus, chiar dacă putem salva boolean, Întreg și Pluti tipuri, reprezentarea subiacentă a acestor tipuri se reîntoarce pe Şir tip. Aceasta înseamnă indiferent de tipul de valoare transmis către setItem () metodă, getItem () metoda va întoarce întotdeauna o valoare care este de tip String. Să examinăm un exemplu de script:

 var integerVariable = 34; localStorage.setItem ("vârstă", integerVariable); var newVariable = localStorage.getItem ("vârstă"); alertă (typeof (newVariable) == "număr");

În scriptul de mai sus, în cele din urmă valoarea integerVariable este salvat ca String. Prin urmare, când inspectăm tipul de variabilă nouă după ce obținem valoarea din spațiul de stocare local, acesta nu mai este un tip întreg și, prin urmare, instrucțiunea de comparare va fi evaluată la falsă. În astfel de situații, trebuie să folosim utilitatea parseInt (String) și parseFloat (String) funcții pentru conversie. Nu există nicio funcție de analizat boolean tipul de date, astfel încât trebuie doar să comparăm valoarea preluată cu șiruri "adevărate" sau "false".

În cele din urmă, pentru a obține declarația de comparație în scriptul de mai sus pentru a evalua Adevărat, trebuie să ne modificăm codul pentru a folosi funcția parseInt () așa cum se arată în următorul script:

 var integerVariable = 34; localStorage.setItem ("vârstă", integerVariable); var newVariable = parseInt (localStorage.getItem ("vârstă")); alertă (typeof (newVariable) == "număr");

Acum, când scriptul de mai sus este executat, tipul valorii stocate în newVariable va fi Întreg. Ulterior, declarația de comparație va evalua la Adevărat.

Atunci când datele persistă ajung la cota de 5 MB, browserele web nu oferă posibilitatea de a solicita mai mult spațiu în spațiul de stocare local. Ei aruncă locul QUOTA_EXCEEDED_ERR excepție de a notifica script-ul că nu mai există spațiu. Cea mai simplă metodă de a face față acestei excepții este să prindeți excepția și să anunțați utilizatorul despre această problemă.

Alternativ, atunci când capturați excepția, scriptul poate șterge unele intrări cheie / valoare din spațiul de stocare local pentru a elibera spațiu pentru perechi noi.

În cele din urmă, atunci când documentul este solicitat direct de pe disc și nu de la un server web, spațiul de stocare local va fi șters de fiecare dată când navigați departe de pagină.

Evenimente de stocare web

Standardul Web Storage permite script-urilor să fie notificate când alte părți ale codului adaugă, actualizează sau șterg intrări din spațiul de stocare local. Astfel, ori de câte ori ceva se schimbă în spațiul de stocare local, a Eveniment de stocare va face foc. Cu toate acestea, în cazul ștergerii unei intrări utilizând o cheie neexistentă, nu va fi declanșat niciun eveniment. Acest lucru se datorează faptului că nimic nu se va schimba în spațiul de stocare local. Din păcate, testele mele au demonstrat că browserele Webkit (cum ar fi Safari și Chrome) nu declanșează Evenimente de stocare așa cum este descris de specificația Web Storage. Browserele Internet Explorer, Firefox și Opera se comportă așa cum era de așteptat.

Un eveniment local de stocare nu poate fi anulat. Singurul său scop este să notifice codul utilizatorului despre o schimbare care sa produs în interiorul spațiului de stocare local.

Următorul script vă arată cum să ascultați schimbări în spațiul de stocare local, prin înregistrarea unui handler de evenimente care va fi apelat de fiecare dată a Eveniment de stocare este concediat:

 dacă (window.addEventListener) window.addEventListener ("stocare", handleStorageChange, false);  altfel window.attachEvent ("onstorage", handleStorageChange);  handleStorageChange (eveniment) alert ("Ceva a fost schimbat în spațiul de stocare local"); 

Deoarece nici o versiune a Internet Explorer (cu excepția versiunii 9 previzualizare publică) acceptă sistemul de tratare a evenimentelor DOM Level 2, attacheEvent () metoda trebuie utilizată pentru a înregistra înregistratorii de evenimente.

eveniment Argumentul este util deoarece transporta informații despre schimbările din spațiul de stocare local. Acesta aderă la StorageEvent interfaţă:

 interfață de stocareEvent: Eveniment readonly String cheie; readonly Object OLDVALUE; readonly obiect newValue; read String URL-ul; ; 

cheie proprietatea identifică ce pereche cheie / valoare a fost modificată. OLDVALUE si newValue proprietățile se comportă așa cum sugerează numele lor. Adică, ele conțin, respectiv, valoarea anterioară și cea nouă pentru cheie.

În cele din urmă, URL-ul proprietatea conține adresa documentului pentru care spațiul de stocare local a fost modificat. Cu toate acestea, datorită unor iterații multiple de implementare a specificației de stocare Web, în ​​unele browsere Web, URL-ul proprietatea poate fi implementată ca uri. Prin urmare, este mai bine să verificați mai întâi URL-ul proprietate și apoi uri în cazul în care URL-ul proprietatea este nedefinită.

Demo

După ce am citit acest lucru, de obicei îmi place să văd un exemplu înainte să cred totul. Ca și mine, sunt sigur că mulți dintre voi ar dori, de asemenea, să vadă un exemplu de lucru. Nu este o problemă, pentru că am pregătit un mic script care demonstrează pur și simplu utilizarea standardului de stocare web într-o aplicație de lucru.

Este făcută astfel încât să poată fi testată, de asemenea, folosind iPhone Safari și browserul web Android. Ideea este ca browserul să-și amintească ce cutii au fost deschise înainte de a utiliza spațiul de stocare local. Te las cu acest cod pentru a te juca cu:

         

Demonstrație Web Storage

Această pagină a fost proiectată pentru a demonstra pur și simplu utilizarea Web Storage în browserele moderne. În acest exemplu, casetele care nu au fost încă apăsate rămân negre. După ce faceți clic pe o cutie neagră, culoarea reală va fi dezvăluită. Cu toate acestea, browserul îți va aminti care sunt dulapurile pe care le faceți clic, chiar și atunci când navigați departe de această pagină. Continuați, faceți o încercare.

Cod