Real-World Off-Line de stocare a datelor

În multe proiecte vine un moment în care va trebui să stocați anumite date off-line. Poate fi o cerință sau doar o îmbunătățire pentru utilizatorii dvs., dar trebuie să decideți care dintre opțiunile de stocare disponibile pe care le veți folosi în aplicația dvs. Acest articol vă va ajuta să alegeți cea mai bună pentru aplicația dvs..


Introducere

HTML5 a introdus câteva opțiuni de stocare offline. AppCache, localStorage, sessionStorage și IndexedDB. Fiecare dintre ele este potrivit pentru o utilizare specifică. De exemplu, aplicația AppCache poate stimula aplicația dvs. sau poate lăsa unele părți din ea să funcționeze fără o conexiune la Internet. Mai jos, voi descrie toate aceste opțiuni și voi afișa câteva fragmente de cod cu exemple de utilizare.


AppCache

Dacă o parte din aplicația dvs. (sau întreaga aplicație) poate fi utilizată fără acces la server, puteți utiliza AppCache pentru a permite utilizatorilor să facă anumite lucruri off-line. Tot ce trebuie să faceți este să creați un fișier manifest în care să specificați ce ar trebui să fie stocat în cache și ce nu ar trebui să fie. De asemenea, puteți specifica înlocuirile pentru fișierele care necesită acces on-line.

Un manifest AppCache este doar un fișier text cu a .AppCache (recomandată). Începe cu CACHE MANIFEST și este împărțit în trei părți:

  • CACHE - fișierele pe care le specificați aici vor fi descărcate și stocate în memoria cache prima dată când utilizatorul accesează site-ul dvs.
  • REŢEA - aici veți lista fișierele care necesită o conexiune la Internet pentru a funcționa corect, acestea nu vor fi niciodată stocate în cache
  • DA ÎNAPOI - aceste fișiere vor fi utilizate atunci când este accesată o resursă on-line fără o conexiune

Exemplu

Mai întâi, trebuie să definiți fișierul manifest pe pagina dvs.:

  ... 

Trebuie să vă amintiți că fișierul manifest trebuie să fie servit cu un a Text / cache-manifest Tip MIME, altfel nu va fi analizat de browser. Apoi, trebuie să creați fișierul pe care l-ați definit mai devreme. În scopul acestui exemplu, să ne imaginăm că aveți un site informativ cu capacitatea de a vă contacta și de a scrie comentarii. Puteți permite utilizatorilor să acceseze părțile statice ale site-ului și să înlocuiască formularul de contact și comentariile cu alte informații, astfel încât formularul și comentariile să fie inaccesibile în timp ce sunt dezactivate.

În primul rând, să definim un conținut static:

 CACHE MANIFEST CACHE: /about.html /portfolio.html /portfolio_gallery/image_1.jpg /portfolio_gallery/image_2.jpg /info.html /style.css/main.js/jquery.min.js

Side Notă: un lucru rău în legătură cu manifestarea este că nu puteți utiliza un semn de semnătură pentru a indica faptul că, de exemplu, un dosar întreg ar trebui să fie stocat în cache, puteți utiliza doar o caracteristică wildcard în secțiunea NETWORK pentru a indica faptul că toate resursele care nu sunt listate în manifest nu ar trebui să fie stocate în cache.

Nu este necesar să stocați în memoria cache pagina pe care este definit manifestul, acesta va fi stocat automat în cache. Acum vom defini rezervări pentru secțiunile de contact și comentarii:

 FALLBACK: /contact.html /offline.html /comments.html /offline.html

În cele din urmă, putem folosi un * pentru a opri toate celelalte resurse de a fi stocate în cache:

 REȚEA: *

Rezultatul final ar trebui să arate astfel:

 CACHE MANIFEST CACHE: /about.html /portfolio.html /portfolio_gallery/image_1.jpg /portfolio_gallery/image_2.jpg /info.html /style.css/main.js/jquery.min.js FALLBACK: /contact.html / offline .html /comments.html /offline.html NETWORK: *

Un lucru important de reținut este că resursele dvs. vor fi cachete o singură dată. Nu vor fi stocate în cache atunci când le actualizați, numai când schimbați manifestul. O bună practică este să introduceți un comentariu cu un număr de versiune și să îl creșteți de fiecare dată când actualizați fișierul:

 CACHE MANIFEST # versiunea 1 CACHE: ... 

LocalStorage & SessionStorage

Aceste două opțiuni de stocare vor fi utile dacă doriți să păstrați ceva în codul dvs. JavaScript. Primul vă permite să salvați o valoare fără o dată de expirare. Această valoare va fi accesibilă pentru orice pagină cu același domeniu și protocol. De exemplu, este posibil să doriți să salvați setările de aplicație ale utilizatorului pe computerul său, astfel încât să le poată adapta la computerul pe care îl utilizează în prezent. Al doilea va menține valorile până când utilizatorul va închide fereastra browserului (sau fila). De asemenea, datele nu sunt partajate între ferestre, chiar dacă utilizatorul deschide câteva pagini ale aplicației.

Ceva ce merită să ne amintim este că puteți să stocați numai tipuri de bază în localStorage/sessionStorage. Deci, numai șiruri de caractere și numere vor funcționa. Orice altceva va fi stocat cu ajutorul lui toString () metodă. Dacă trebuie să salvați un obiect, trebuie să îl utilizați JSON.stringify (dacă acest obiect este o clasă, puteți doar să înlocuiți setarea implicită toString () metoda de a face acest lucru pentru tine în mod automat).

Exemplu

Să luăm în considerare exemplul anterior. În secțiunile de comentarii și de contact ale site-ului, putem salva ceea ce a introdus utilizatorul, astfel încât, dacă închide accidental fereastra, valorile vor fi în continuare acolo pentru ca el / ea să poată continua mai târziu. Aceasta va fi o bucată foarte simplă de cod folosind jQuery (deoarece vom folosi id-ul unui domeniu pentru ao identifica mai târziu, fiecare dintre câmpurile de formular va trebui să aibă un atribut id)

 $ ('# comments-input, .contact-field') pe ('keyup', function () // sa verificam daca localStorage este suportat daca (window.localStorage) localStorage.setItem ('id'), $ (acest) .val ()););

Când se trimite formularul de comentariu / contact, trebuie să ștergem valoarea. Să facem acest lucru gestionând un eveniment de prezentare (aici este cel mai de bază exemplu):

 $ ('# comments-form, # formular de contact') pe ('submit', funcția () // obține toate câmpurile pe care le-am salvat $ ('# comments-input,. (funcția () // obține ID-ul câmpului și scoate-l din stocarea locală localStorage.removeItem ($ (this) .attr ('id'));););

Și în final, la încărcarea paginii, vom restabili valorile:

 // a lua toate câmpurile pe care le-am salvat $ ('# comments-input, .contact-field') fiecare (function () // obține ID-ul câmpului și obține valoarea acestuia din stocarea locală var val = localStorage.getItem (acest) .attr ('id')); // dacă valoarea există, setați-o dacă (val) $ (this) .val (val););

IndexedDB

Aceasta este cea mai interesantă opțiune de stocare în opinia mea. Acesta vă permite să stocați cantități mari de date indexate în browser-ul utilizatorului. În acest fel, puteți salva obiecte complexe, documente mari etc., iar utilizatorul dvs. le poate accesa fără o conexiune la Internet. Această caracteristică este utilă pentru toate tipurile de aplicații - dacă faceți un client de e-mail, puteți salva e-mailurile utilizatorului, astfel încât să le poată accesa mai târziu, un album foto poate salva fotografii pentru utilizarea offline sau navigarea prin GPS poate salva un anumit traseu și lista continuă.

IndexedDB este o bază de date orientată pe obiecte. Aceasta înseamnă că nu există tabele și nici SQL. Se stochează perechi de date cheie-valoare, unde cheile sunt șiruri, numere, date sau matrice și valori pot fi obiecte complexe. Baza de date în sine este compusă din magazine. Un magazin este similar cu un tabel într-o bază de date relațională. Fiecare valoare trebuie să aibă cheia proprie. O cheie poate fi generată automat, o puteți specifica când adăugați valoarea sau poate fi un câmp în valoare (care poate fi, de asemenea, generat automat). Dacă decideți să utilizați un câmp ca o cheie, veți putea să adăugați obiecte JavaScript în magazin (deoarece numerele simple sau șirurile nu pot avea proprietăți cum ar fi obiectele).

Exemplu

Pentru acest exemplu, să ne imaginăm că avem un album muzical. Acum nu voi acoperi construirea întregii aplicații de muzică aici. Voi acoperi numai partea indexedDB a aplicației, dar aplicația albumului de muzică în sine este inclusă în acest articol pentru descărcare, astfel încât să puteți vedea codul sursă complet acolo. În primul rând, trebuie să deschidem baza de date și să creăm magazinul:

 // verificați dacă indexedDB este acceptat dacă (! window.indexedDB) throw 'IndexedDB nu este suportat!'; // desigur înlocuiți acest lucru cu o notificare ușor de utilizat // variabilă care va ține legătura de bază de date var db; // deschide baza de date // primul argument este numele bazei de date, al doilea este versiunea lui (vom vorbi despre versiuni într-un timp) var request = indexedDB.open ('album', 1); request.onerror = funcția (e) console.log (e); ; // aceasta se va declanșa când versiunea bazei de date se modifică request.onupgradeneeded = funcția (e) // e.target.result menține conexiunea la baza de date db = e.target.result; // a crea un magazin care să dețină datele // primul argument este numele magazinului, al doilea este pentru opțiuni // aici specificăm câmpul care va servi ca cheie și vom permite, de asemenea, generarea automată a tastelor cu autoIncrement var objectStore = db. createObjectStore ("cds", keyPath: 'id', autoIncrement: true); // crea un index pentru a căuta CD-uri după titlu // primul argument este numele indexului, al doilea este câmpul din valoarea // în ultimul argument specificăm alte opțiuni, aici afirmăm doar că indicele este unic, pentru că există să fie un singur album cu titlul specific objectStore.createIndex ('title', 'title', unique: true); // crea un index pentru a căuta cd-uri pe bandă // aceasta nu este unică, deoarece o singură bandă poate avea mai multe albume objectStore.createIndex ('band', 'band', unique: false); ;

Codul de mai sus este destul de simplu. Probabil ați observat versiunea și onupgradeneeded eveniment. Acest eveniment este declanșat când baza de date este deschisă cu o nouă versiune. Deoarece baza de date nu exista încă, evenimentul se declanșează și putem crea magazinul de care avem nevoie. Mai târziu, adăugăm două indexuri, unul pentru a căuta după titlu și unul pentru a căuta după banda. Acum, să vedem procesul de adăugare și eliminare a albumelor:

 // adăugați $ ('# add-album') pe ('click', funcția () // crea tranzacția // primul argument este o listă de magazine care va fi utilizată, a doua specifică pavilionul // doriți să adăugați ceva de care avem nevoie de acces la scriere, așa că folosim flagul readwrite var transaction = db.transaction (['cds'], 'readwrite'), transaction.onerror = funcția (e) console.log (e); var valoare = ...; // citeste din DOM // adauga albumul la magazin var request = transaction.objectStore ('cds') add (value); request.onsuccess = function (e) // adauga albumul către UI, e.target.result este o cheie a elementului adăugat;); // elimina $ ('. remove-album') pe ('click', function () var transaction = db.transaction ('cds' ') .delete (/ * un id primit de la DOM, convertit la integer * /); request.onsuccess = function () // elimina albumul din UI);

Destul de direct. Trebuie să vă amintiți că toate operațiile din baza de date se bazează pe tranzacții pentru a păstra coerența datelor. Acum, singurul lucru de făcut este să afișați albumele:

 request.onsuccess = funcția (e) if (! db) db = e.target.result; var tranzacție = db.transaction (['cds']); // nu există pavilion, deoarece citim doar magazinul var = transaction.objectStore ('cds'); // deschideți un cursor, care va primi toate elementele din baza de date store.openCursor (). onsuccess = funcția (e) var cursor = e.target.result; dacă (cursor) var value = cursor.value; $ ('# albums-list tbody'). append (''+ value.title +''+ value.band +''+ value.genre +''+ valoare.aeară +'„); // trece la următorul element din cursor cursor.continue (); ; 

Acest lucru nu este, de asemenea, foarte complicat. După cum puteți vedea, utilizând IndexedDB puteți stoca foarte ușor valorile complexe. De asemenea, puteți căuta valori după index, după cum urmează:

 funcția getAlbumByBand (bandă) var transaction = db.transaction (['cds']); var magazin = transaction.objectStore ("cds"); var index = store.index ("banda"); // deschideți un cursor pentru a obține numai albume cu banda specificată // observați argumentul transmis la openCursor () index.openCursor (IDBKeyRange.only (bandă)) onsuccess = funcție (e) var cursor = e.target.result; dacă (cursor) // render albumul // muta la următorul element din cursor cursor.continue (); ); 

Puteți folosi cursorul cu indexul la fel cum am făcut-o cu magazinul. Întrucât pot exista câteva intrări cu aceeași valoare a indexului (dacă nu este unică), trebuie să utilizăm IDBKeyRange. Aceasta va filtra rezultatele în funcție de funcția pe care o utilizați. Aici, vrem să obținem numai articole de la banda furnizată, așa că am folosit-o numai() metodă. Puteți utiliza, de asemenea limita inferioară(), limită superioară() și legat. Numele de metode sunt destul de explicative.


Concluzie

Deci, permiterea accesului off-line pentru utilizatorii dvs. nu este atât de complicată cum pare. Sper că după ce ați citit acest articol, veți face aplicațiile dvs. mai ușor de utilizat, permițându-le să acceseze anumite părți (sau poate chiar toate) din acestea fără o conexiune la Internet. Puteți descărca aplicația pentru eșantioane și puteți experimenta cu aceasta, adăugând mai multe opțiuni sau inclusiv anumite părți ale acesteia în site-ul dvs. Web.

Cod