Archiviazione del browser per app HTML5

Per anni uno dei principali vantaggi della scrittura di applicazioni desktop è stato il facile accesso allo storage locale sul computer client. Gli sviluppatori Web hanno sopportato l'impossibilità di archiviare e recuperare i dati dalla macchina del cliente per un lungo periodo, ma sembra che potrebbe cambiare presto. Potresti persino pensarlo già dopo aver letto questo articolo. Sì, ho intenzione di discutere le origini dei dati persistenti sul computer client e quindi di introdurvi allo standard di archiviazione Web.

La maggior parte degli sviluppatori web sa che l'unico tipo di archiviazione locale che ci si potrebbe aspettare da un browser web si presenta sotto forma di cookie. Bene, non interamente. Il desiderio di archiviare dati sulla macchina client non è un concetto nuovo e non è stato concepito durante la creazione di specifiche HTML5. Ciò che è ancora più sorprendente è che un'implementazione funzionante è stata sviluppata da Microsoft come parte del set di funzionalità IE6. Lo hanno chiamato dati utente e in sostanza garantiva almeno 640 KB di spazio locale per dominio in base alle politiche di sicurezza IE impostate dall'utente. Potrebbe sembrare uno spazio molto piccolo rispetto allo standard odierna, ma quando lo confrontiamo con il massimo spazio 4KB a nostra disposizione dai cookie, il miglioramento è apprezzabile.

Cosa c'è di sbagliato con i cookie?

Un certo numero di cose. Il problema principale dei cookie è che vengono inviati avanti e indietro tra browser e server con ogni richiesta HTTP. Questo non è un comportamento desiderabile, perché più spesso gli sviluppatori non desiderano trasmettere dati locali al server più di una volta, se non una volta. I cookie non offrono agli sviluppatori alcuna scelta.

Come detto in precedenza, i cookie possono memorizzare solo fino a 4KB di dati. Non sono molti dati, tuttavia 4KB è abbastanza dati da rallentare sensibilmente le richieste di pagina.

Inoltre, i cookie vengono passati avanti e indietro tra il client e il server in chiaro. Pertanto, l'unico modo per proteggerli è la crittografia dei dati durante la comunicazione con il server back-end tramite SSL (Secure Socket Layer). Tuttavia, la maggior parte dei siti Web su Internet non utilizza SSL, che lascia lo storage aperto alle intercettazioni.

Ci sono altri problemi che rendono i cookie meno utili. Idealmente, gli sviluppatori desiderano avere la capacità di mantenere grandi quantità di dati sul computer client e non doverli trasmettere più volte al server.

Quali sono le soluzioni alternative?

Finora non abbiamo discusso soluzioni alternative per i dati persistenti sul computer client. Quando gli sviluppatori di Adobe (allora noti come Macromedia) rilasciavano Flash Player 6, anche loro dovevano affrontare lo stesso problema. Nel 2002, Flash Player 6 ha introdotto una nuova funzionalità denominata Local Shared Object o più spesso conosciuta come Cookie Flash per introdurre efficacemente le stesse funzionalità dei cookie HTTP standard ai film e ai siti Flash. L'oggetto locale condiviso ha consentito agli sviluppatori di mantenere fino a 100 KB di dati sul computer client per impostazione predefinita.

La seconda soluzione è l'implementazione di Google Local Storage come parte del plug-in Gears per Web Browser. Gears era (e ti dico perché lo uso era in un momento) la combinazione di più funzionalità mancanti e utili necessarie per lo sviluppo di Rich Internet Applications (RIA). L'archiviazione locale di Gears si basava sulla specifica Web SQL meno popolare che sfruttava SQLite. Avete indovinato, Gears ha fornito agli sviluppatori un database SQL completo per mantenere una quantità illimitata di dati sul computer client.

Gli sviluppatori di Ajax Massive Storage System (AMASS) hanno colto questa opportunità e sviluppato una libreria JavaScript di terze parti che ha reso possibile per i siti HTML standard di sfruttare la funzionalità Local Shared Object in Flash o il plug-in Gears per mantenere i dati sul macchina client. Inoltre, la libreria JavaScript di Dojo è in grado di rilevare la disponibilità di meccanismi di archiviazione locale (ad esempio Google Gears, oggetti condivisi locali, ecc.) E fornisce un'interfaccia unificata per i dati persistenti su browser Web diversi.

Tornando al motivo per cui ho detto che Gears 'era' invece che 'still is': è perché Google ha recentemente annunciato che lascerà un ulteriore sviluppo del plug-in di Gears in favore di HTML5 e delle specifiche di Web Storage presentate in questo tutorial.

HTML5 e specifiche di archiviazione Web

Ora che la lezione di storia è finita, impareremo a conoscere il Web Storage e ci immergiamo in qualche codice per comprenderlo meglio. Il modo più semplice per descrivere l'archiviazione Web è la possibilità di mantenere i dati sul computer client sotto forma di una chiave per un valore. Questo è molto simile a come vengono utilizzati gli array associativi:

 "The Key": "The Value"

L'archiviazione locale è progettata per essere supportata nativamente dai browser Web. Ciò significa non più librerie di terze parti e problemi con Flash. Sorprendentemente, Web Storage è stata una delle specifiche di maggior successo in termini di adozione da parte dei browser moderni. Infatti, quasi tutti i browser moderni supportano lo storage Web, tra cui:

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

Sebbene lo scopo di Web Storage sia fornire funzionalità simili ai cookie, è stato ulteriormente perfezionato il fatto di non portare alcuno dei loro attributi negativi. Ad esempio, Web Storage consente di mantenere fino a 5 MB di dati, un notevole aumento di spazio rispetto alla quantità di dati che possono essere memorizzati in un cookie. Inoltre, i dati persistenti che utilizzano Archiviazione Web non comporteranno l'invio di tali dati al back-end del server con ogni richiesta di pagina. Ciò aumenta significativamente le prestazioni. In base alle specifiche di Web Storage, i browser Web espirano solo i dati persistenti dal computer locale quando richiesto dall'utente e eviteranno sempre l'eliminazione dei dati mentre è in esecuzione uno script che potrebbe accedere a tali dati.

I browser Web espongono lo storage Web tramite il memoria locale oggetto in JavaScript. Un modo semplice per determinare se un browser Web può supportare l'archiviazione Web è eseguire questo codice JavaScript:

 var webStorageSupported = ('localStorage' nella finestra) && window ['localStorage']! == null;

Secondo le specifiche del W3C per il Web Storage, il memoria locale oggetto implementa il seguente insieme di metodi e proprietà dall'interfaccia di archiviazione. Esaminiamo ciascuno di questi metodi e proprietà per scoprire cosa fanno e come possono essere utilizzati:

 Interfaccia di archiviazione a sola lettura lunghezza; vuoto setItem (chiave di stringa, dati oggetto); Oggetto getItem (chiave di stringa); vuoto removeItem (chiave di stringa); vuoto chiaro(); Stringa chiave (indice lungo); ; 

Il lunghezza la proprietà è molto utile. Restituirà il numero di coppie chiave / valore attualmente salvate su Archiviazione locale nel dominio attualmente utilizzato:

 alert (localStorage.length);

Se nessuna coppia chiave / valore è stata precedentemente salvata nella memoria locale, lo script precedente visualizzerà una finestra di avviso con "0" come messaggio, altrimenti il ​​messaggio sarà il numero di coppie chiave / valore persistenti.

Il setItem (chiave, valore) metodo semplicemente salva una nuova voce sul computer locale. Per salvare la chiave nome con il valore Arman potremmo eseguire questo script:

 localStorage.setItem ('name', 'arman');

Per garantire quella chiave nome è stato veramente salvato nella memoria locale con il valore Arman dobbiamo usare il getItem (chiave) metodo. Il getItem metodo semplicemente accetta una chiave e cerca nella memoria locale per trovare una chiave corrispondente e quindi restituisce il suo valore.

 localStorage.setItem ('name', 'arman'); var value = localStorage.getItem ('name'); alert (valore);

Se si esegue lo script di cui sopra si dovrebbe vedere una finestra di avviso contenente la parola Arman appare sullo schermo, confermando che abbiamo salvato con successo una nuova coppia chiave / valore nella memoria locale. Dal momento che il memoria locale l'oggetto si comporta in modo analogo agli array associativi, potremmo semplificare lo script precedente in modo che assomigli a questo e continuerà a funzionare lo stesso:

 localStorage ['name'] = 'arman'; var value = localStorage ['name']; alert (valore);

Diamo un'occhiata a removeItem (chiave) metodo. Questo metodo è progettato per rimuovere una coppia chiave / valore precedentemente salvata dalla memoria locale. Se la chiave non esiste, questo metodo semplicemente non fa nulla. Il seguente esempio di codice dimostra l'uso di Rimuovi oggetto metodo:

 localStorage.setItem ('name', 'arman'); localStorage.removeItem ( 'name'); var value = localStorage.getItem ('name'); alert (valore);

Quando viene eseguito lo script sopra, dovresti vedere una finestra di avviso con il valore nullo nella casella di avviso. Usando il nome chiave, lo script precedente crea semplicemente una nuova coppia chiave / valore e la rimuove immediatamente dalla memoria locale. Successivamente, viene restituito un valore nullo quando si accede alla memoria locale con lo stesso nome chiave.

Verranno occasioni in cui sarà necessario cancellare completamente la memoria locale e iniziare con una lavagna pulita. Il chiaro() il metodo è progettato esattamente per quello scopo. Questo metodo svuota automaticamente tutte le coppie chiave / valore precedentemente salvate dalla memoria locale. Se non ci sono voci, nulla cambierà.

 localStorage.setItem ('name', 'arman'); localStorage.setItem ('name', 'smith'); localStorage.setItem ('name', 'frank'); alert (localStorage.length); localStorage.clear (); alert (localStorage.length);

Sebbene lo script precedente crei tre nuove coppie chiave / valore (come evidenziato dal primo avviso), la chiamata al metodo clear () rimuove tutte le voci. Successivamente, la seconda finestra di avviso visualizzerà un messaggio "0".

Il metodo finale che dobbiamo guardare è il chiave (indice) metodo. Questo metodo recupera il nome di una chiave in base al parametro indice. memoria locale mantiene un elenco basato su 0 di tutte le voci al suo interno. Pertanto per accedere alla prima chiave dalla memoria locale, è necessario utilizzare 0 come indice come illustrato in questo script:

 localStorage.clear (); localStorage.setItem ('age', 5); alert (localStorage.key (0));

Quando viene eseguito lo script precedente, dovrebbe visualizzare una finestra di avviso con il messaggio "age". Notare come nell'esempio precedente la prima riga di codice cancella la memoria locale. Questo per garantire che iniziamo con una lavagna pulita. Un'altra utile applicazione del chiave() il metodo è in congiunzione con il lunghezza proprietà. Ad esempio, per ottenere tutte le coppie chiave / valore dalla memoria locale senza conoscere le chiavi in ​​anticipo, potremmo scrivere uno script come il seguente:

 localStorage.clear (); localStorage.setItem ("title", "Mr."); localStorage.setItem ("fullname", "Aaron Darwin"); localStorage.setItem ("age", 17); localStorage.setItem ("height", 182.5); per (var i = 0; i < localStorage.length; i++)  var keyName = localStorage.key(i); var value = localStorage.getItem(keyName); alert(keyName + " = " + value); 

Nello script precedente, il nostro codice prima cancella e quindi aggiunge quattro nuove coppie chiave / valore alla memoria locale. Quindi usa il lunghezza proprietà in a Per loop per elaborare la chiave per ogni coppia chiave / valore. Ad ogni iterazione del ciclo il tasto è assegnato al keyName variabile che viene quindi passata al getItem () metodo per recuperare il suo valore.

Le sottigliezze

Quando si accede ai dati utilizzando una chiave che non esiste nella memoria locale, invece di un'eccezione, a nullo il valore è sempre restituito. Ciò rende difficile sapere se il valore della chiave è nullo o la chiave semplicemente non esiste nella memoria locale.

Il secondo di cui parlare è il setItem (chiave, valore) metodo. Sappiamo che possiamo passare qualsiasi tipo di valore al setItem () metodo per il valore parametro, ma non è completamente vero. In JavaScript, siamo in grado di creare Immagine oggetti. Tuttavia, l'attuale implementazione di Web Storage consente solo tipi persistenti primitivi come Stringa, booleano, Numero intero e Galleggiante tipi. Pertanto, possiamo aspettarci che il seguente script generi un'eccezione e un arresto anomalo:

 var imageObject = new Image ("http://www.google.com/logo.gif"); localStorage.setItem ("image", imageObject);

Inoltre, anche se possiamo salvare booleano, Numero intero e Galleggiante tipi, la rappresentazione sottostante di questi tipi ricade sul Stringa genere. Ciò significa indipendentemente dal tipo di valore passato a setItem () metodo, il getItem () il metodo restituirà sempre un valore che è di tipo String. Diamo un'occhiata a uno script di esempio:

 var integerVariable = 34; localStorage.setItem ("age", integerVariable); var newVariable = localStorage.getItem ("age"); alert (typeof (newVariable) == "numero");

Nello script sopra, in definitiva il valore del integerVariable viene salvato come stringa. Pertanto, quando ispezioniamo il tipo di nuova variabile dopo aver ottenuto il suo valore dall'archivio locale, non è più un tipo Integer e quindi l'istruzione di confronto verrà valutata come falsa. In tali situazioni, dobbiamo usare il pratico parseInt (String) e parseFloat (String) funzioni per la conversione. Non c'è alcuna funzione da analizzare booleano tipo di dati, quindi dobbiamo semplicemente confrontare il valore recuperato con stringhe "true" o "false".

Infine, per ottenere la dichiarazione di confronto nello script sopra da valutare vero, dobbiamo modificare il nostro codice per utilizzare la funzione parseInt () come mostrato nel seguente script:

 var integerVariable = 34; localStorage.setItem ("age", integerVariable); var newVariable = parseInt (localStorage.getItem ("age")); alert (typeof (newVariable) == "numero");

Ora, quando viene eseguito lo script sopra, il tipo del valore memorizzato nel file newVariable sarà Numero intero. Successivamente, l'istruzione di confronto valuterà vero.

Quando i dati persistenti raggiungono la quota di 5 MB, i browser Web non offrono la possibilità di chiedere più spazio nella memoria locale. Loro invece lanciano il QUOTA_EXCEEDED_ERR eccezione per notificare allo script che non c'è più spazio. Il modo più semplice per gestire questa eccezione è rilevare l'eccezione e informare l'utente del problema.

In alternativa, quando si cattura l'eccezione, lo script può eliminare alcune voci chiave / valore dall'archivio locale per liberare spazio per nuove coppie.

Infine, quando il documento viene richiesto direttamente dal disco e non da un server Web, la memoria locale viene cancellata ogni volta che si allontana dalla pagina.

Eventi di archiviazione Web

Web Storage Standard consente agli script di essere avvisati quando altre parti del codice aggiungono, aggiornano o cancellano le voci dalla memoria locale. Pertanto, ogni volta che qualcosa cambia nella memoria locale, a Evento di archiviazione sta per sparare. Tuttavia, nel caso di eliminazione di una voce utilizzando una chiave non esistente, non verrà generato alcun evento. Questo perché nulla cambierà nella memoria locale. Sfortunatamente, i miei test hanno dimostrato che attualmente i browser Webkit (come Safari e Chrome) non attivano il Eventi di archiviazione come descritto dalla specifica di Web Storage. I browser Internet Explorer, Firefox e Opera si comportano come previsto.

Un evento di archiviazione locale non può essere annullato. Il suo unico scopo è di notificare al codice utente una modifica avvenuta all'interno della memoria locale.

Il seguente script mostra come ascoltare le modifiche nella memoria locale, registrando un gestore di eventi che verrà chiamato ogni volta a Evento di archiviazione è licenziato:

 if (window.addEventListener) window.addEventListener ("storage", handleStorageChange, false);  else window.attachEvent ("onstorage", handleStorageChange);  function handleStorageChange (event) alert ("Qualcosa è cambiato nella memoria locale"); 

Poiché nessuna versione di Internet Explorer (ad eccezione dell'anteprima pubblica della versione 9) supporta il sistema di gestione degli eventi DOM di livello 2, il attacheEvent () il metodo deve essere usato per registrare i gestori di eventi.

Il evento argomento è utile perché porta informazioni sulle modifiche nella memoria locale. Aderisce al StorageEvent interfaccia:

 interfaccia StorageEvent: evento stringa readonly chiave; Oggetto readonly oldValue; oggetto readonly newValue; stringa di sola lettura url; ; 

Il chiave proprietà identifica quale coppia chiave / valore è stata cambiata. Il oldValue e il newValue le proprietà si comportano come suggeriscono i loro nomi. Cioè, rispettivamente contengono il precedente e il nuovo valore per la chiave.

Finalmente, il url proprietà contiene l'indirizzo del documento per il quale è stata appena modificata la memoria locale. Tuttavia, a causa di più iterazioni di implementazione delle specifiche di archiviazione Web, in alcuni browser Web il url la proprietà può essere implementata come uri. Quindi è meglio prima controllare il url proprietà e poi uri nel caso in cui il url la proprietà non è definita.

dimostrazione

Dopo aver letto molto, di solito mi piace vedere un esempio prima di credere a tutto. Proprio come me, sono sicuro che molti di voi vorrebbero vedere un esempio funzionante. Questo non è un problema, perché ho preparato un piccolo script che dimostra semplicemente l'uso dello standard di archiviazione web in un'applicazione funzionante.

È realizzato in modo tale da poter essere testato anche utilizzando iPhone Safari e il browser Web Android. L'idea è di far ricordare al browser quali caselle sono state aperte prima di utilizzare la memoria locale. Ti lascerò con questo codice per giocare con:

         

Demo di archiviazione Web

Questa pagina è stata progettata per dimostrare semplicemente l'utilizzo di Web Storage nei browser moderni. In questo esempio le caselle che non sono ancora state cliccate rimangono nere. Una volta che fai clic su una scatola nera, verrà rivelato il vero colore. Il browser, tuttavia, ricorderà quali caselle sono state selezionate, anche quando ci si allontana da questa pagina. su, provaci.