web-dev-qa-db-fra.com

Quand les éléments du stockage local HTML5 expirent-ils?

Pendant combien de temps les données stockées dans localStorage (dans le cadre du stockage DOM en HTML5) sont-elles disponibles? Puis-je définir un délai d'expiration pour les données que je mets dans localStorage?

302
user280427

Il n'est pas possible de spécifier une expiration. C'est complètement à l'utilisateur.

https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage

Bien sûr, il est possible que quelque chose que votre application stocke sur le client ne soit pas là plus tard. L'utilisateur peut explicitement se débarrasser du stockage local ou le navigateur peut rencontrer des problèmes d'espace. C'est bien de programmer de manière défensive. Cependant, en règle générale, les choses restent "pour toujours" sur la base d'une définition pratique de cette Parole.

edit - de toute évidence, votre propre application peut supprimer activement des éléments si elle décide qu'elle est trop ancienne. Autrement dit, vous pouvez explicitement inclure une sorte d’horodatage dans ce que vous avez enregistré, puis l’utiliser plus tard pour décider si les informations doivent être vidées ou non.

192
Pointy

Je suggère de stocker timestamp dans le objet vous stockez dans le localStorage

var object = {value: "value", timestamp: new Date().getTime()}
localStorage.setItem("key", JSON.stringify(object));

Vous pouvez analyser l'objet, obtenir l'horodatage et le comparer à la date actuelle et, si nécessaire, mettre à jour la valeur de l'objet.

var object = JSON.parse(localStorage.getItem("key")),
    dateString = object.timestamp,
    now = new Date().getTime().toString();

compareTime(dateString, now); //to implement
246
sebarmeli

Vous pouvez utiliser lscache . Il gère cela automatiquement pour vous, y compris les cas où la taille de stockage dépasse la limite. Si cela se produit, il commence à élaguer les éléments les plus proches de leur expiration spécifiée.

De la readme:

lscache.set

Stores the value in localStorage. Expires after specified number of minutes.

Arguments
key (string)
value (Object|string)
time (number: optional)

C’est la seule différence réelle entre les méthodes de stockage habituelles. Obtenez, supprimez, etc. fonctionnent de la même manière.

Si vous n'avez pas besoin de beaucoup de fonctionnalités, vous pouvez simplement stocker un horodatage avec la valeur (via JSON) et en vérifier l'expiration.

Il convient de noter qu'il y a une bonne raison pour laquelle le stockage local est laissé à l'utilisateur. Mais des choses comme lscache sont pratiques lorsque vous devez stocker des données extrêmement temporaires.

34
huyz

Brynner Ferreira a apporté un bon point: stocker une clé de frère où se trouvent les informations d'expiration. Ainsi, si vous avez un grand nombre de clés ou si vos valeurs sont de grands objets Json, vous n'avez pas besoin de les analyser pour accéder à l'horodatage.

voici une version améliorée:

 /*  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;
}
31
Fernando Fabreti

Alors que le stockage local ne fournit pas de mécanisme d'expiration, les cookies le font. Le simple fait d'associer une clé de stockage locale à un cookie constitue un moyen simple de s'assurer que le stockage local peut être mis à jour avec les mêmes paramètres d'expiration qu'un cookie.

Exemple dans 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

Cet exemple définit un cookie avec le paramètre par défaut pour expirer lorsque le navigateur est fermé. Ainsi, lorsque le navigateur est fermé et rouvert, le magasin de données local de your_data est actualisé par un appel côté serveur.

Notez que ce n'est pas exactement la même chose que supprimer le magasin de données local. Il met plutôt à jour le magasin de données local à l'expiration du cookie. Cependant, si votre objectif principal est de pouvoir stocker plus de 4K côté client (la limitation de la taille du cookie), cette association de cookie et de stockage local vous aidera à obtenir une taille de stockage plus grande en utilisant les mêmes paramètres d'expiration qu'un cookie. .

23
Robert Peake

Ici fortement recommandé d'utiliser sessionStorage

  • il est identique à localStorage mais détruit à la fermeture de la session/du navigateur
  • sessionStorage est également utile pour réduire le trafic réseau contre les cookies.

pour utiliser la valeur définie

sessionStorage.setItem("key","my value");

pour obtenir une utilisation de valeur

var value = sessionStorage.getItem("key");

cliquez ici pour voir api

tous les moyens sont

  sessionStorage.key = "my val";
  sessionStorage["key"] = "my val";
  sessionStorage.setItem("key","my value");

tous les moyens pour obtenir sont

  var value = sessionStorage.key;
  var value = sessionStorage["key"];
  var value = sessionStorage.getItem("key");

Le cycle de vie est contrôlé par l'application/l'utilisateur.

De la standard :

Les agents d'utilisateur doivent expirer les données des zones de stockage locales uniquement pour des raisons de sécurité ou à la demande de l'utilisateur. Les agents utilisateurs doivent toujours éviter de supprimer des données lorsqu'un script pouvant accéder à ces données est en cours d'exécution.

13
jldupont

Du brouillon du W3C:

Les agents d'utilisateur doivent expirer les données des zones de stockage locales uniquement pour des raisons de sécurité ou à la demande de l'utilisateur. Les agents utilisateurs doivent toujours éviter de supprimer des données lorsqu'un script pouvant accéder à ces données est en cours d'exécution.

Vous voudrez faire vos mises à jour sur votre planning en utilisant setItem (clé, valeur); cela ajoutera ou mettra à jour la clé donnée avec les nouvelles données.

9
FatherStorm
// 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); }

}
9
Brynner Ferreira

Si quelqu'un cherche encore une solution rapide et ne veut pas de dépendances telles que jquery, etc. J'ai écrit une mini-lib qui ajoute l'expiration au stockage local/session/personnalisé, vous pouvez le trouver avec le source ici:

https://github.com/RonenNess/ExpiredStorage

3
Ronen Ness

Si quelqu'un utilise le plugin jStorage de jQuery, il peut être ajouté une date d'expiration avec la fonction setTTL si le plugin jStorage

$.jStorage.set('myLocalVar', "some value");
$.jStorage.setTTL("myLocalVar", 24*60*60*1000); // 24 Hr.
3
Amit

À mon avis, l'approche de @ sebarmeli est la meilleure, mais si vous voulez que les données persistent pendant toute la durée d'une session, alors sessionStorage est probablement une meilleure option:

Il s'agit d'un objet global (sessionStorage) qui conserve une zone de stockage disponible pour la durée de la session de page. Une session de page dure aussi longtemps que le navigateur est ouvert et survit après un rechargement et une restauration de page. Si vous ouvrez une page dans un nouvel onglet ou une nouvelle fenêtre, une nouvelle session sera lancée.

MDN: sessionStorage

1
Kevin Leary

Solution de contournement utilisant angular et 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
        }
      })
    }
  }

})
1
Tomas Romero

Au profit des chercheurs:

Comme Fernando, je ne voulais pas ajouter une charge de json lorsque les valeurs stockées étaient simples. Je devais juste suivre certaines interactions de l'interface utilisateur et garder les données pertinentes (par exemple, comment un utilisateur utilisait un site de commerce électronique avant de passer à la caisse).

Cela ne répondra pas à tous les critères, mais nous espérons être un démarreur rapide copier/coller pour quelqu'un et sauvegarder en ajoutant un autre lib.

Remarque: cela ne serait pas bon si vous devez récupérer les éléments individuellement.

// 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]);
    }
}
1
HockeyJ

Vous pouvez essayer celui-ci.

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);
    }
}
0
Jay Chauhan