Vorremo rendere disponibile questo progetto open-source per persone in tutto il mondo.
Aiutaci a tradurre il contenuto di questo tutorial nella tua lingua!
LocalStorage, sessionStorage
Gli oggetti web storage localStorage e sessionStorage permetto di salvare le coppie key/value nel browser. Ciò che è interessante è che i dati rimangono memorizzati anche in seguito al ricaricamento della pagina (per sessionStorage) e anche in seguito a un riavvio del browser (per localStorage). Vedremo come.
Abbiamo già a disposizione i cookies. Perché usare altri oggetti?
- Rispetto ai cookies, gli oggetti web storage non vengono inviati al server con ogni richiesta. Per questo motivo, possiamo archiviarne molti di più. La maggior parte dei browser permette almeno 2 megabytes di dati (o più) e possiedono impostazioni per configurare questa scelta.
- Inoltre, il server non può manipolare la memorizzazione degli oggetti tramite HTTP headers. Tutto viene fatto in JavaScript.
- L’archiviazione è legata alla sorgete (origin) (domain/protocol/port triplet). Questo perché, protocolli differenti o sotto domini deducono diverse archiviazioni a oggetti e non possono accedere ai dati tra di loro.
Le due archiviazioni a oggetti propongono stessi metodi e proprietà:
setItem(key, value): memorizza la coppia key/value.getItem(key): lettura del valore dalla key.removeItem(key): rimuove la key, ed il relativo value.clear(): rimuove tutti gli elementi.key(index): lettura della key all’indiceindex.length: il numero di oggetti archiviati.
Come potete vedere, è simile alla collezione Map (setItem/getItem/removeItem), mantiene comunque l’ordine degli elementi e permette il loro accesso tramite indice con key(index).
Vediamo come funziona.
localStorage demo
Le caratteristiche principali di localStorage sono:
- Condivisione tra le tabs e finestre provenienti dalla stessa origine.
- I dati non scadono. Rimangono in seguito a un riavvio del browser o dell’intero sistema operativo.
Per esempio, il seguente esempio:
…E chiudiamo/apriamo il browser o semplicemente apriamo la stessa pagina in una finestra diversa, possiamo ottenere il risultato atteso in questo modo:
Dobbiamo solo essere nello stesso punto di partenza (domain/port/protocol), l’URL di destinazione può essere differente.
Il localStorage è condiviso tra tutte le finestre con la stessa provenienza, quindi se impostiamo i dati in una finestra, il cambiamento diventa visibile anche nelle altre schede.
Accesso in stile oggetto
Possiamo usare la stessa sintassi di lettura/scrittura degli oggetti per accedere agli elementi, in questo modo:
Questo è permesso per ragioni storiche, e principalmente funziona, ma generalmente non è raccomandato, perché:
-
Se la key è generata dall’utente, può essere qualsiasi cosa, come
lengthotoString, o un altro metodo integrato dilocalStorage. In questo casogetItem/setItemfunziona normalmente, mentre l’accesso in stile oggetto non funziona: -
C’è un evento
storage, che viene emesso quando modifichiamo dati. Questo evento viene per gli accessi in stile oggetto. Vedremo più avanti nel capitolo.
Cicli sulle keys
Come abbiamo visto, i metodi forniscono funzionalità get/set/remove. Ma come otteniamo tutti i valori o keys salvate?
Sfortunatamente, gli oggetti archiviati non sono iterabili.
Una soluzione sarebbe quella di eseguire un loop su di loro come un array:
Un altro modo è quello di usare un loop for key in localStorage , come facciamo con oggetti regolari.
L’iterazione avverrà sulle keys, ma anche sugli outputs di campi associati ad alcune funzioni built-in di cui non abbiamo bisogno:
… dunque dobbiamo filtrare i campi dal prototype con il controllo hasOwnProperty:
…oppure possiamo ottenere le keys “proprie” con Object.keys ed eseguire il loop su di loro se necessario:
Un lavoro extra, poiché Object.keys restituisce solo le keys che appartengono all oggetto, ignorando il prototype.
Solo stringhe
Da notare che sia key che i value devono essere stringhe.
Se ci fosse un altro tipo di dato, come un numero, o un object, verrebbe automaticamente convertito a stringa:
Possiamo usare JSON per archiviare oggetti:
Inoltre è possibile convertire a stringa l’intero archivio di oggetti, per esempio per motivi di debugging:
sessionStorage
L’oggetto sessionStorage è usato molto meno spesso del localStorage.
Proprietà e metodi sono gli stessi, ma è più limitato:
- La
sessionStorageesiste solo all’intero della tab del browser corrente.- Un’altra tab con la stessa pagina avrà un archiviazione differente.
- Viene comunque condivisa tra iframes nella stessa tab (assumendo che la loro provenienza sia la stessa).
- I dati sopravvivono al refresh della pagina, ma non alla chiusura/apertura della tab.
Vediamo come si comporta.
Esegui questo codice…
…Poi ricarica la pagina. Pra potrai comunque ottenere i dati:
…Ma se apri la stessa pagina in un’altra tab, e provi di nuovo, dal codice otterrai null, ovvero “non è stato trovato nulla”.
Questo perché sessionStorage è legato non solo all’origine, ma anche alla tab del browser. Per questo motivo, sessionStorage è usato sporadicamente.
Evento di storage
Quando i dati vengono aggiornati in localStorage o sessionStorage, un evento di storage viene emesso, con le seguenti proprietà:
key: La key che è stata modificata (nullse è stato invocato.clear()).oldValue: Il vecchio valore (nullse la chiave è nuova).newValue: il nuovo valore (nullse la chiave è sta rimossa).URL: L’URL del documento in cui è avvenuto l’aggiornamento.storageArea: se l’aggiornamento è avvenuto inlocalStorageosessionStorage.
La cosa importante è: l’evento si attiva in tutti gli oggetti window dove l’archivio è accessibile, ad eccezione per quello in cui è stato causato.
Elaboriamo.
Immaginate di avere due finestre aperte con lo stesso sito all’interno. Quindi localStorage è condiviso tra le due.
Dovresti aprire questa pagina in due browser per testare il seguente codice.
Se entrambe le finestre sono connesse a window.onstorage, allora reagiranno agli aggiornamenti che accadono in una delle due.
// attiva un aggiornamento fatto dallo stesso archivio degli altri documenti
window.onstorage = event => { // identico a window.addEventListener('storage', event => {
if (event.key != 'now') return;
alert(event.key + ':' + event.newValue + " at " + event.URL);
};
localStorage.setItem('now', Date.now());
Notare che l’evento contiene: event.URL – l’URL del documento in cui i dati sono stati aggiornati.
Inoltre, event.storageArea contiene lo storage object – l’evento è lo stesso per entrambi sessionStorage e localStorage, quindi event.storageArea si rivolge a quello che è stato modificato. Potremmo anche impostare qualcosa all’interno, per “rispondere” al cambiamento.
That allows different windows from the same origin to exchange messages.
I browser moderni supportano Broadcast channel API, un API speciale per comunicazione inter-finestra provenienti dalla stessa sorgente, possiede molte più funzionalità ma è meno supportata. Esistono librerie che sostituiscono quella API, basate su localStorage, che lo rendono disponibile ovunque.
Riepilogo
Gli oggetti web storage localStorage e sessionStorage permettono di archiviare key/value nel browser.
- Sia
keyevaluedevono essere stringhe. - Il limite è 2mb+, dipende dal browser.
- Non scadono.
- I dati sono legati alla sorgente (domain/port/protocol).
localStorage |
sessionStorage |
|---|---|
| Condivise tra tutte le tabs e finestre provenienti dalla stessa sorgente | Visibile all’interno di una tab del browser, incluso iframes della stessa origine |
| Sopravvivono al riavvio del browser | Sopravvivono al refresh della pagina (ma non alla chiusura della tab) |
API:
setItem(key, value): archivia coppia key/value .getItem(key): legge il valore dalla chiave.removeItem(key): rimuove la chiave con il suo valore.clear(): cancella tutto.key(index): legge il valore all’indiceindex.length: il numero di oggetti archiviati.- Utilizza
Object.keysper ottenere tutte le chiavi. - Accediamo alle keys come proprietà degli oggetti, in questo caso l’evento
storagenon verrà emesso.
Evento di storage:
- Emesso su chiamata di
setItem,removeItem,clear. - Contiene tutti i data riguardo l’operazione (
key/oldValue/newValue), il documentoURLe lo storage objectstorageArea. - Emesso su tutti gli oggetti
windowche hanno accesso all’archivio eccetto quello da cui è stato generato (all’interno di una tab persessionStorage, globalmente perlocalStorage).
Esercizi
Create un campo di textarea che “auto salva” il suo contenuto ad ogni cambiamento.
Quindi se l’utente chiude accidentalmente la pagina, e la riapre, troverà il suo input come in precedenza.
Come nell’esempio:
- © 2007—2026 Ilya Kantor
- riguardo il progetto
- contattaci
Commenti
<code>, per molte righe – includile nel tag<pre>, per più di 10 righe – utilizza una sandbox (plnkr, jsbin, codepen…)