Real-World Off-Line Datalagring

I mange prosjekter kommer det en tid da du må lagre noen data offline. Det kan være et krav eller bare en forbedring for brukerne, men du må bestemme hvilke av de tilgjengelige lagringsalternativene du vil bruke i søknaden din. Denne artikkelen hjelper deg med å velge det beste for appen din.


Introduksjon

HTML5 introduserte noen få lagringsalternativer for off-line. AppCache, LocalStorage, sessionStorage og IndexedDB. Hver og en av dem er egnet for en bestemt bruk. AppCache kan for eksempel øke søknaden din eller la noen deler av det fungere uten en Internett-tilkobling. Nedenfor vil jeg beskrive alle disse alternativene og vise noen kodestykker med eksempelbruk.


AppCache

Hvis en del av søknaden din (eller hele appen) kan brukes uten tilgang til serveren, kan du bruke AppCache for å gjøre det mulig for brukerne å gjøre noen ting offline. Alt du trenger å gjøre er å opprette en manifestfil der du spesifiserer hva som skal bufres og hva som ikke skal være. Du kan også angi utskiftninger for filene som krever online-tilgang.

Et AppCache-manifest er bare en tekstfil med en .AppCache (anbefalt) forlengelse. Det starter med CACHE MANIFEST og er delt inn i tre deler:

  • CACHE - filer du spesifiserer her vil bli lastet ned og hurtigbufret første gang brukeren får tilgang til nettstedet ditt
  • NETTVERK - her lister du filene som krever en Internett-tilkobling for å fungere skikkelig, de blir aldri cached
  • FALLE TILBAKE - Disse filene vil bli brukt når en online ressurs er tilgjengelig uten tilkobling

Eksempel

Først må du definere manifestfilen på siden din:

  ... 

Du må huske at manifestfilen må serveres med en tekst / cache-manifest MIME-typen, ellers vil den ikke bli analysert av nettleseren. Deretter må du opprette filen du definerte tidligere. For formålet med dette eksemplet, kan vi forestille oss at du har et informasjonsnettsted med muligheten til å kontakte deg og skrive kommentarer. Du kan la brukerne få tilgang til de statiske delene av nettstedet og erstatte kontaktskjemaet og kommentarene med annen informasjon, slik at skjemaet og kommentarene er utilgjengelige mens off-line.

La oss først definere noe statisk innhold:

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

Side Merk: En dårlig ting om manifestet er at du ikke kan bruke et wildcard-tegn for å indikere at for eksempel en hel mappe skal bufret, du kan bare bruke et jokertegn under NETTVERK-seksjonen for å indikere at alle ressurser ikke er oppført i manifestet bør ikke bufres.

Du trenger ikke å cache siden der manifestet er definert, det vil bli cached automatisk. Nå vil vi definere fallbacks for kontakt og kommentarer seksjoner:

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

Til slutt kan vi bruke en * for å stoppe alle andre ressurser fra å bli cached:

 NETTVERK: *

Det endelige resultatet skal se slik ut:

 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 NETTVERK: *

En viktig ting å huske er at ressursene dine bare vil bli cached en gang. De blir ikke cached når du oppdaterer dem, bare når du endrer manifestet. En god praksis er å skrive inn en kommentar med et versjonsnummer og øke det hver gang du oppdaterer filen:

 CACHE MANIFEST # versjon 1 CACHE: ... 

LocalStorage & SessionStorage

Disse to lagringsalternativene vil være nyttige hvis du vil bevare noe i JavaScript-koden din. Den første lar deg lagre en verdi uten en utløpsdato. Denne verdien vil være tilgjengelig for alle sider med samme domene og protokoll. For eksempel kan du lagre brukerens programinnstillinger på sin datamaskin slik at han / hun kan justere dem til datamaskinen de bruker. Den andre vil holde verdiene til brukeren lukker nettleservinduet (eller fanen). Også dataene deles ikke mellom vinduer, selv om brukeren åpner noen sider av søknaden din.

Noe verdt å huske er at du bare kan lagre grunnleggende typer i lokal lagring/sessionStorage. Så bare strenger og tall vil fungere. Alt annet vil bli lagret ved hjelp av det toString () metode. Hvis du trenger å lagre et objekt, bør du gjøre det ved å bruke JSON.stringify (Hvis dette objektet er en klasse, kan du bare overstyre standardinnstillingen toString () metode for å gjøre det for deg automatisk).

Eksempel

La oss vurdere det forrige eksemplet. I kommentarene og kontaktene på nettstedet kan vi lagre det som brukeren skrev inn, så hvis han / hun ved et uhell lukker vinduet, vil verdiene fortsatt være der for ham / henne å fortsette senere. Dette vil være et veldig enkelt stykke kode ved hjelp av jQuery (siden vi skal bruke et felt ID for å identifisere det senere, må hver formularfelt ha et id-attributt)

 $ ('# comments-input, .contact-field'). på ('keyup', funksjon () // la oss sjekke om localStorage støttes hvis (window.localStorage) localStorage.setItem ($ (this) .attr ('id'), $ (dette) .val ()););

Når kommentaren / kontaktskjemaet sendes, må vi slette verdien. La oss gjøre dette ved å håndtere en sendehendelse (her er det mest grunnleggende eksempelet):

 $ ('# comments-form, # contact-form'). på ('send', funksjon () // få alle feltene vi lagret $ ('# comments-input, .contact-field'). (funksjon () // få feltets id og fjern det fra lokal lagring localStorage.removeItem ($ (this) .attr ('id'));););

Og til slutt, på sidebelastning, vil vi gjenopprette verdiene:

 // få alle feltene vi lagret $ ('# comments-input, .contact-field'). hver (funksjon () // få feltets id og få det til verdi fra lokal lagring var val = localStorage.getItem ($ (dette) .attr ('id')); // hvis verdien eksisterer, sett den hvis (val) $ (dette) .val (val););

IndexedDB

Dette er det mest interessante lagringsalternativet etter min mening. Den lar deg lagre ganske store mengder indeksert data inn i brukerens nettleser. På denne måten kan du lagre komplekse objekter, store dokumenter, etc., og få brukeren tilgang til dem uten en Internett-tilkobling. Denne funksjonen er nyttig for alle typer applikasjoner. Hvis du lager en e-postklient, kan du lagre brukerens e-postadresser, slik at han eller hun kan få tilgang til dem senere, et fotoalbum kan lagre bilder for bruk utenfor nettet eller GPS-navigasjon kan lagre en bestemt rute og listen fortsetter.

IndexedDB er en objektorientert database. Dette betyr at det ikke er noen tabeller og ingen SQL. Du lagrer nøkkelverdige datapar, hvor taster er strenger, tall, datoer eller arrayer og verdier kan være komplekse objekter. Databasen selv består av butikker. En butikk ligner et bord i en relasjonsdatabase. Hver verdi må ha sin egen nøkkel. En nøkkel kan genereres automatisk, du kan spesifisere den når du legger til verdien, eller det kan være noe felt i verdien (som også kan genereres automatisk). Hvis du bestemmer deg for å bruke et felt som en nøkkel, kan du bare legge til JavaScript-objekter i butikken (fordi enkle tall eller strenger ikke kan ha noen egenskaper som objekter kan).

Eksempel

For dette eksempelet, la oss forestille oss at vi har et musikkalbum. Nå skal jeg ikke dekke å bygge hele musikkalbum-appen her. Jeg vil bare dekke IndexedDB-delen av appen, men selve musikkalbum-appen er inkludert i denne artikkelen for å laste ned, slik at du kan se på den komplette kildekoden der. Først må vi åpne databasen og opprette butikken:

 // Sjekk om indeksertDB støttes hvis (! window.indexedDB) kaste 'IndexedDB ikke støttes!'; // selvfølgelig erstatte det med noe brukervennlig varsel // variabel som vil holde databasen tilkoblingen var db; // åpne databasen // første argumentet er databasens navn, det andre er det er versjonen (jeg snakker om versjoner om en stund) var request = indexedDB.open ('album', 1); request.onerror = funksjon (e) console.log (e); ; // dette vil brenne når versjonen av databasen endres request.onupgradeneeded = function (e) // e.target.result holder forbindelsen til databasen db = e.target.result; // lage en butikk for å holde dataene // første argumentet er butikkens navn, det andre er for alternativer // her angir vi feltet som skal fungere som nøkkel og også aktivere automatisk generering av nøkler med autoIncrement var objectStore = db. createObjectStore ('cds', keyPath: 'id', autoIncrement: true); // lage en indeks for å søke CDer etter tittel // første argument er indeksens navn, andre er feltet i verdien // i det siste argumentet angir vi andre alternativer, her angir vi bare at indeksen er unik, fordi det kan vær bare ett album med bestemt tittelobjektStore.createIndex ('title', 'title', unique: true); // lage en indeks for å søke CDer etter band // dette er ikke unikt, siden ett band kan ha flere album objectStore.createIndex ('band', 'band', unikt: false); ;

Ovennevnte kode er ganske enkel. Du har sikkert lagt merke til versjonen og onupgradeneeded begivenhet. Denne hendelsen slås av når databasen åpnes med en ny versjon. Siden databasen ikke eksisterte, bryr hendelsen og vi kan opprette butikken vi trenger. Senere legger vi til to indekser, en for å søke etter tittel og en for å søke etter band. La oss nå se prosessen med å legge til og fjerne album:

 // (legg til $ ('# add-album'). på ('klikk', funksjon () // opprett transaksjonen // første argumentet er en liste over butikker som skal brukes, andre spesifiserer flagget // siden vi Vil du legge til noe vi trenger skrive tilgang, så bruker vi readwrite flagg transaction = db.transaction (['cds'], 'readwrite'); transaction.onerror = funksjon (e) console.log (e);; var verdi = ...; // les fra DOM // legg albumet til butikken var request = transaction.objectStore ('cds'). legg til (verdi); request.onsuccess = funksjon (e) // legg til album til brukergrensesnittet, e.target.result er en nøkkel til elementet som ble lagt til;); / / fjerning av $ ('fjern-album'). på ('klikk', funksjon () var transaksjon = db.transaction (['cds'], 'readwrite'); var request = transaction.objectStore ') .delete (/ * Noen id er hentet fra DOM, konvertert til heltall * /); request.onsuccess = function () // fjern albumet fra brukergrensesnittet);

Ganske rett fram. Du må huske at alle operasjoner i databasen er basert på transaksjoner for å bevare konsistens av data. Nå er det eneste som igjen er å vise albumene:

 request.onsuccess = funksjon (e) if (! db) db = e.target.result; var transaksjon = db.transaction (['cd'er']); // ingen flagg siden vi bare leser var butikk = transaction.objectStore ('cds'); // åpne en markør, som vil få alle elementene fra database store.openCursor (). onsuccess = funksjon (e) var markør = e.target.result; hvis (markør) var value = cursor.value; $ ('# albums-list tbody'). append (''+ value.title +''+ value.band +''+ value.genre +''+ verdi.år +''); // flytte til neste element i markøren cursor.continue (); ; 

Dette er heller ikke veldig komplisert. Som du kan se, bruker IndexedDB du kan lagre komplekse verdier veldig enkelt. Du kan også søke etter verdier etter indeks, slik:

 funksjon getAlbumByBand (bånd) var transaksjon = db.transaction (['cd'er']); var butikk = transaction.objectStore ('cds'); var index = store.index ('band'); // åpne en markør for å bare få album med spesifisert band // legge merke til argumentet passert til openCursor () index.openCursor (IDBKeyRange.only (band)). onsuccess = funksjon (e) var cursor = e.target.result; hvis (markør) // gjør albumet // flytt til neste objekt i markøren cursor.continue (); ); 

Du kan bruke markøren med indeksen akkurat som hvordan vi gjorde med butikken. Siden det kan være noen få oppføringer med samme indeksverdi (hvis det ikke er unikt), må vi bruke IDBKeyRange. Dette vil filtrere resultatene avhengig av hvilken funksjon du bruker. Her vil vi bare få varer av det medfølgende bandet, så vi brukte bare() metode. Du kan også bruke lowerbound (), øvre grense() og bundet. Metoden navnene er ganske selvforklarende.


Konklusjon

Så det er ikke så komplisert at det kan virke som mulig å få tilgang til Internett for brukerne. Jeg håper at etter å ha lest denne artikkelen, vil du gjøre applikasjonene dine mer brukervennlige ved å la dem få tilgang til enkelte deler (eller kanskje alle) uten en Internett-tilkobling. Du kan laste ned prøveappen og eksperimentere med den, legge til flere alternativer eller inkludere noen deler av det på nettstedet ditt.