Per quanto tempo sono disponibili i dati memorizzati in localStorage (come parte di DOM Storage in HTML5)? Posso impostare un tempo di scadenza per i dati che inserisco in localStorage?
Per quanto tempo sono disponibili i dati memorizzati in localStorage (come parte di DOM Storage in HTML5)? Posso impostare un tempo di scadenza per i dati che inserisco in localStorage?
Risposte:
Non è possibile specificare la scadenza. Dipende completamente dall'utente.
https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
Ovviamente, è possibile che qualcosa che l'applicazione memorizza sul client potrebbe non essere presente in seguito. L'utente può eliminare esplicitamente l'archiviazione locale o il browser può eseguire considerazioni sullo spazio. È bene programmare in modo difensivo. In genere, tuttavia, le cose rimangono "per sempre" sulla base di una definizione pratica di quella parola.
modifica - ovviamente, la tua applicazione può rimuovere attivamente roba se decide che è troppo vecchia. Cioè, puoi includere esplicitamente una sorta di data / ora in ciò che hai salvato e quindi usarlo in seguito per decidere se le informazioni devono essere scaricate o meno.
Suggerirei di memorizzare il timestamp nell'oggetto che memorizzi nel localStorage
var object = {value: "value", timestamp: new Date().getTime()}
localStorage.setItem("key", JSON.stringify(object));
È possibile analizzare l'oggetto, ottenere il timestamp e confrontarlo con la data corrente e, se necessario, aggiornare il valore dell'oggetto.
var object = JSON.parse(localStorage.getItem("key")),
dateString = object.timestamp,
now = new Date().getTime().toString();
compareTime(dateString, now); //to implement
settimout
per ogni 5 secondi) o per ogni richiesta che il client invia al server?
Puoi usare lscache . Gestisce questo per te automaticamente, compresi i casi in cui la dimensione della memoria supera il limite. In tal caso, inizia a eliminare gli oggetti più vicini alla scadenza specificata.
Dal readme
:
lscache.set
Stores the value in localStorage. Expires after specified number of minutes.
Arguments
key (string)
value (Object|string)
time (number: optional)
Questa è l'unica vera differenza tra i normali metodi di archiviazione. Ottieni, rimuovi, ecc. Funziona allo stesso modo.
Se non hai bisogno di molte funzionalità, puoi semplicemente memorizzare un timestamp con il valore (tramite JSON) e verificarne la scadenza.
Degno di nota, c'è una buona ragione per cui l'archiviazione locale è lasciata all'utente. Ma cose come lscache sono utili quando è necessario archiviare dati estremamente temporanei.
Brynner Ferreira, ha portato un buon punto: memorizzare una chiave di pari livello dove risiedono le informazioni di scadenza. In questo modo, se si dispone di una grande quantità di chiavi o se i valori sono oggetti Json di grandi dimensioni , non è necessario analizzarli per accedere al timestamp.
qui segue una versione migliorata:
/* removeStorage: removes a key from localStorage and its sibling expiracy key
params:
key <string> : localStorage key to remove
returns:
<boolean> : telling if operation succeeded
*/
function removeStorage(name) {
try {
localStorage.removeItem(name);
localStorage.removeItem(name + '_expiresIn');
} catch(e) {
console.log('removeStorage: Error removing key ['+ key + '] from localStorage: ' + JSON.stringify(e) );
return false;
}
return true;
}
/* getStorage: retrieves a key from localStorage previously set with setStorage().
params:
key <string> : localStorage key
returns:
<string> : value of localStorage key
null : in case of expired key or failure
*/
function getStorage(key) {
var now = Date.now(); //epoch time, lets deal only with integer
// set expiration for storage
var expiresIn = localStorage.getItem(key+'_expiresIn');
if (expiresIn===undefined || expiresIn===null) { expiresIn = 0; }
if (expiresIn < now) {// Expired
removeStorage(key);
return null;
} else {
try {
var value = localStorage.getItem(key);
return value;
} catch(e) {
console.log('getStorage: Error reading key ['+ key + '] from localStorage: ' + JSON.stringify(e) );
return null;
}
}
}
/* setStorage: writes a key into localStorage setting a expire time
params:
key <string> : localStorage key
value <string> : localStorage value
expires <number> : number of seconds from now to expire the key
returns:
<boolean> : telling if operation succeeded
*/
function setStorage(key, value, expires) {
if (expires===undefined || expires===null) {
expires = (24*60*60); // default: seconds for 1 day
} else {
expires = Math.abs(expires); //make sure it's positive
}
var now = Date.now(); //millisecs since epoch time, lets deal only with integer
var schedule = now + expires*1000;
try {
localStorage.setItem(key, value);
localStorage.setItem(key + '_expiresIn', schedule);
} catch(e) {
console.log('setStorage: Error setting key ['+ key + '] in localStorage: ' + JSON.stringify(e) );
return false;
}
return true;
}
else
linea non dovrebbe essere expires = Math.abs(1000*expires); //make sure it's positive
?
getStorage
chiamata. Se provi ad accedere direttamente alla _expiresIn
versione della chiave, la chiave diventa quella ..._expiresIn_expiresIn
che ovviamente non esiste, quindi rimuove la ..._expiresIn
chiave originale , quindi la prossima volta che accedi alla chiave originale, la ..._expiresIn
non esiste e cancella l'originale chiave. Suggerirei di intrappolarlo mentre mi imbattevo in uno dei miei progetti. if(key.indexOf('_expiresIn') > -1) { return localStorage.getItem(key); }
Mentre l'archiviazione locale non fornisce un meccanismo di scadenza, i cookie lo fanno. Il semplice accoppiamento di una chiave di archiviazione locale con un cookie fornisce un modo semplice per garantire che l'archiviazione locale possa essere aggiornata con gli stessi parametri di scadenza di un cookie.
Esempio in jQuery:
if (!$.cookie('your_key') || !localStorage.getItem('your_key')) {
//get your_data from server, then...
localStorage.setItem('your_key', 'your_data' );
$.cookie('your_key', 1);
} else {
var your_data = localStorage.getItem('your_key');
}
// do stuff with your_data
In questo esempio un cookie con il parametro predefinito scade alla chiusura del browser. Pertanto, quando il browser viene chiuso e riaperto, l'archivio dati locale per your_data viene aggiornato da una chiamata sul lato server.
Si noti che ciò non è esattamente uguale alla rimozione dell'archivio dati locale, ma aggiorna l'archivio dati locale ogni volta che scade il cookie. Tuttavia, se il tuo obiettivo principale è quello di essere in grado di archiviare più di 4K lato client (la limitazione per le dimensioni dei cookie), questa associazione di cookie e archiviazione locale ti aiuterà a raggiungere dimensioni di archiviazione maggiori utilizzando gli stessi parametri di scadenza di un cookie .
Qui si consiglia vivamente di utilizzare sessionStorage
per l'uso del valore impostato
sessionStorage.setItem("key","my value");
per ottenere valore
var value = sessionStorage.getItem("key");
clicca qui per visualizzare api
tutti i modi per impostare sono
sessionStorage.key = "my val";
sessionStorage["key"] = "my val";
sessionStorage.setItem("key","my value");
tutti i modi per ottenere sono
var value = sessionStorage.key;
var value = sessionStorage["key"];
var value = sessionStorage.getItem("key");
sessionStorage
non funziona per condividere i dati tra le schede
Il ciclo di vita è controllato dall'applicazione / utente.
Dallo standard :
I programmi utente devono far scadere i dati dalle aree di archiviazione locali solo per motivi di sicurezza o quando richiesto dall'utente. Gli interpreti dovrebbero sempre evitare di eliminare i dati mentre è in esecuzione uno script che potrebbe accedere a tali dati.
Dalla bozza del W3C:
I programmi utente devono far scadere i dati dalle aree di archiviazione locali solo per motivi di sicurezza o quando richiesto dall'utente. Gli interpreti dovrebbero sempre evitare di eliminare i dati mentre è in esecuzione uno script che potrebbe accedere a tali dati.
Ti consigliamo di fare gli aggiornamenti sul tuo programma usando setItem (chiave, valore); che aggiungerà o aggiornerà la chiave fornita con i nuovi dati.
// Functions
function removeHtmlStorage(name) {
localStorage.removeItem(name);
localStorage.removeItem(name+'_time');
}
function setHtmlStorage(name, value, expires) {
if (expires==undefined || expires=='null') { var expires = 3600; } // default: 1h
var date = new Date();
var schedule = Math.round((date.setSeconds(date.getSeconds()+expires))/1000);
localStorage.setItem(name, value);
localStorage.setItem(name+'_time', schedule);
}
function statusHtmlStorage(name) {
var date = new Date();
var current = Math.round(+date/1000);
// Get Schedule
var stored_time = localStorage.getItem(name+'_time');
if (stored_time==undefined || stored_time=='null') { var stored_time = 0; }
// Expired
if (stored_time < current) {
// Remove
removeHtmlStorage(name);
return 0;
} else {
return 1;
}
}
// Status
var cache_status = statusHtmlStorage('cache_name');
// Has Data
if (cache_status == 1) {
// Get Cache
var data = localStorage.getItem('cache_name');
alert(data);
// Expired or Empty Cache
} else {
// Get Data
var data = 'Pay in cash :)';
alert(data);
// Set Cache (30 seconds)
if (cache) { setHtmlStorage('cache_name', data, 30); }
}
Se qualcuno sta ancora cercando una soluzione rapida e non desidera dipendenze come jquery ecc. Ho scritto una mini lib che aggiunge la scadenza all'archiviazione locale / sessione / personalizzata, puoi trovarla qui con l'origine:
Puoi provare questo.
var hours = 24; // Reset when storage is more than 24hours
var now = new Date().getTime();
var setupTime = localStorage.getItem('setupTime');
if (setupTime == null) {
localStorage.setItem('setupTime', now)
} else {
if(now-setupTime > hours*60*60*1000) {
localStorage.clear()
localStorage.setItem('setupTime', now);
}
}
Soluzione alternativa utilizzando angular e localforage:
angular.module('app').service('cacheService', function() {
return {
set: function(key, value, expireTimeInSeconds) {
return localforage.setItem(key, {
data: value,
timestamp: new Date().getTime(),
expireTimeInMilliseconds: expireTimeInSeconds * 1000
})
},
get: function(key) {
return localforage.getItem(key).then(function(item) {
if(!item || new Date().getTime() > (item.timestamp + item.expireTimeInMilliseconds)) {
return null
} else {
return item.data
}
})
}
}
})
localforage
. expireTimeInMilliseconds
non è un localforage
attributo, ma una variabile che ho usato per verificare se i dati memorizzati devono essere scaduti. Controlla la get
definizione della funzione sul mio esempio.
localforage
non è il piccolo aiutante leggero che mi aspettavo
Secondo me, l'approccio di @ sebarmeli è il migliore, ma se vuoi che i dati persistano per la durata di una sessione, sessionStorage
probabilmente è un'opzione migliore:
Questo è un oggetto globale (sessionStorage) che mantiene un'area di archiviazione disponibile per la durata della sessione della pagina. Una sessione di pagina dura fino a quando il browser è aperto e sopravvive a ricariche e ripristini di pagine. L'apertura di una pagina in una nuova scheda o finestra comporterà l'avvio di una nuova sessione.
A beneficio dei ricercatori:
Come Fernando, non volevo aggiungere un carico di json quando i valori memorizzati erano semplici. Avevo solo bisogno di tenere traccia di alcune interazioni dell'interfaccia utente e mantenere i dati pertinenti (ad esempio, come un utente ha utilizzato un sito di e-commerce prima di effettuare il checkout).
Questo non soddisferà i criteri di tutti, ma si spera che sia una copia veloce + incolla un avviatore per qualcuno e salvi l'aggiunta di un'altra lib.
NOTA: ciò non sarebbe utile se è necessario recuperare gli elementi singolarmente.
// Addition
if(window.localStorage){
localStorage.setItem('myapp-' + new Date().getTime(), 'my value');
}
// Removal of all expired items
if(window.localStorage){
// two mins - (1000 * 60 * 20) would be 20 mins
var expiryTime = new Date().getTime() - (1000 * 60 * 2);
var deleteRows = [];
for(var i=0; i < localStorage.length; i++){
var key = localStorage.key(i);
var partsArray = key.split('-');
// The last value will be a timestamp
var lastRow = partsArray[partsArray.length - 1];
if(lastRow && parseInt(lastRow) < expiryTime){
deleteRows.push(key);
}
}
// delete old data
for(var j=0; j < deleteRows.length; j++){
localStorage.removeItem(deleteRows[j]);
}
}
Se hai familiarità con l' oggetto locaStorage del browser , sai che non è previsto un termine di scadenza. Tuttavia, possiamo usare Javascript per aggiungere un TTL (Time to live) per invalidare gli articoli in locaStorage dopo un certo periodo di tempo.
function setLocalStorage(key, value, ttl) {
// `item` is an object which contains the original value
// as well as the time when it's supposed to expire
const item = {
value: value,
expiry: ttl <= 0 ? -1 : new Date().getTime() + ttl
};
localStorage.setItem(key, JSON.stringify(item));
}
function getLocalStorage(key) {
const itemStr = localStorage.getItem(key);
// if the item doesn't exist, return null
if (!itemStr) {
return null;
}
const item = JSON.parse(itemStr);
// compare the expiry time of the item with the current time
if (item.expiry > 0 && new Date().getTime() > item.expiry) {
// If the item is expired, delete the item from storage
// and return null
localStorage.removeItem(key);
return null;
}
return item.value;
}