Solutions de secours du stockage local HTML5 [fermé]

119

Je recherche des bibliothèques javascript et du code pouvant simuler localStoragesur des navigateurs qui n'ont pas de support natif.

Fondamentalement, j'aimerais coder mon site en utilisant localStoragepour stocker des données et savoir qu'il fonctionnera toujours sur les navigateurs qui ne le prennent pas en charge de manière native. Cela signifierait qu'une bibliothèque détecte si elle window.localStorageexiste et l'utilise si elle le fait. S'il n'existe pas, il créerait une sorte de méthode de secours de stockage local, en créant sa propre implémentation dans l' window.localStorageespace de noms.

Jusqu'à présent, j'ai trouvé ces solutions:

  1. Implémentation simple de sessionStorage .
  2. Une implémentation qui utilise des cookies (pas ravie de cette idée).
  3. Dojo's dojox.storage , mais c'est son propre truc, pas vraiment une solution de secours.

Je comprends que Flash et Silverlight peuvent également être utilisés pour le stockage local, mais je n'ai rien trouvé sur leur utilisation comme solution de secours pour HTML5 localStorage standard. Peut-être que Google Gears a également cette capacité?

Veuillez partager toutes les bibliothèques, ressources ou extraits de code associés que vous avez trouvés! Je serais particulièrement intéressé par les solutions purement javascript ou jquery, mais je suppose que c'est peu probable.

Tauren
la source
sessionStorage et localStorage font tous deux partie de la spécification de stockage Web ( dev.w3.org/html5/webstorage ). La seule différence est la durée pendant laquelle le navigateur conservera les données. Je suppose que vous ne trouverez pas d'implémentation où vous en avez une mais pas l'autre (mais je ne suis pas sûr à 100%)
rlovtang
1
Il convient de mentionner que Gears a été officiellement abandonné en février dernier - je ne bâtirais rien dessus.
josh3736
@rlovtang: merci, je suis conscient de la différence entre la session et le stockage local. Selon l'article de 24ways.org (premier lien en question, solution n ° 1), Chrome ne prend en charge que localStorage et non sessionStorage. Ce n'est peut-être plus le cas, car cet article a été écrit il y a quelque temps.
Tauren
@ josh3736: oui, j'aimerais personnellement éviter d'utiliser des cookies et des engrenages. Je ne construirais certainement rien qui en dépende, mais s'il s'agissait d'un mécanisme de stockage de secours pour quelqu'un qui l'avait installé, et que je ne codais pas directement dessus, il pourrait être utilisé.
Tauren
donc je me suis trompé :) Je ne savais pas que Chrome avait une fois pris en charge localStorage mais pas sessionStorage. Chrome prend en charge les deux maintenant au moins.
rlovtang

Réponses:

56

J'utilise PersistJS ( référentiel github ), qui gère le stockage côté client de manière transparente et transparente à votre code. Vous utilisez une seule API et bénéficiez d'une assistance pour les backends suivants:

  • flash: stockage persistant Flash 8.
  • gears: stockage persistant basé sur Google Gears.
  • localstorage: stockage de brouillons HTML5.
  • whatwg_db: stockage de base de données HTML5.
  • globalstorage: stockage de brouillon HTML5 (ancienne spécification).
  • c'est-à-dire: les comportements des données utilisateur d'Internet Explorer.
  • cookie: stockage persistant basé sur les cookies.

Chacun de ceux-ci peut être désactivé, si, par exemple, vous ne souhaitez pas utiliser de cookies. Avec cette bibliothèque, vous bénéficierez d'une prise en charge native du stockage côté client dans IE 5.5+, Firefox 2.0+, Safari 3.1+ et Chrome; et prise en charge assistée par plugin si le navigateur dispose de Flash ou Gears. Si vous activez les cookies, cela fonctionnera dans tout (mais sera limité à 4 ko).

josh3736
la source
10
PersistJS est-il toujours pris en charge? Je me demande comment cela résout un problème où le navigateur est mis à niveau et la méthode de stockage choisie change (disons que le stockage local devient disponible). L'ancien emplacement devient-il inaccessible?
jcalfee314
2
Au moins, il ne semble plus être en développement actif.
Mahn
C'est une bibliothèque très audacieuse. Sans aucune connaissance de la taille maximale dans la plupart des technologies, nous devrions être convaincus que notre application fonctionne avec beaucoup de chance ... De plus, cela semble être uniquement une solution si vous souhaitez économiser <64 Ko.
dude
@julmot C'est à ça que sert une bibliothèque. Fournir de la commodité tout en évitant les choses fastidieuses. Avec suffisamment de recherche et de temps, vous pouvez généralement comprendre comment le faire fonctionner, quelle que soit la taille maximale. Bien sûr, il semble que l'auteur de ce projet ait décidé que c'était trop ...
William
Savez-vous si cela fonctionne avec le mode de navigation privée Safari? Actuellement, je rencontre un problème où localStorage n'est pas pris en charge dans la navigation privée Safari à la fois macOS et iOS.
Austin le
61

Polyfill de stockage local simple basé sur JS pur:

Démo: http://jsfiddle.net/aamir/S4X35/

HTML:

<a href='#' onclick="store.set('foo','bar')">set key: foo, with value: bar</a><br/>
<a href='#' onclick="alert(store.get('foo'))">get key: foo</a><br/>
<a href='#' onclick="store.del('foo')">delete key: foo</a>​

JS:

window.store = {
    localStoreSupport: function() {
        try {
            return 'localStorage' in window && window['localStorage'] !== null;
        } catch (e) {
            return false;
        }
    },
    set: function(name,value,days) {
        if (days) {
            var date = new Date();
            date.setTime(date.getTime()+(days*24*60*60*1000));
            var expires = "; expires="+date.toGMTString();
        }
        else {
            var expires = "";
        }
        if( this.localStoreSupport() ) {
            localStorage.setItem(name, value);
        }
        else {
            document.cookie = name+"="+value+expires+"; path=/";
        }
    },
    get: function(name) {
        if( this.localStoreSupport() ) {
            var ret = localStorage.getItem(name);
            //console.log(typeof ret);
            switch (ret) {
              case 'true': 
                  return true;
              case 'false':
                  return false;
              default:
                  return ret;
            }
        }
        else {
            // cookie fallback
            /*
             * after adding a cookie like
             * >> document.cookie = "bar=test; expires=Thu, 14 Jun 2018 13:05:38 GMT; path=/"
             * the value of document.cookie may look like
             * >> "foo=value; bar=test"
             */
            var nameEQ = name + "=";  // what we are looking for
            var ca = document.cookie.split(';');  // split into separate cookies
            for(var i=0;i < ca.length;i++) {
                var c = ca[i];  // the current cookie
                while (c.charAt(0)==' ') c = c.substring(1,c.length);  // remove leading spaces
                if (c.indexOf(nameEQ) == 0) {  // if it is the searched cookie
                    var ret = c.substring(nameEQ.length,c.length);
                    // making "true" and "false" a boolean again.
                    switch (ret) {
                      case 'true':
                          return true;
                      case 'false':
                          return false;
                      default:
                          return ret;
                    }
                }
            }
            return null; // no cookie found
        }
    },
    del: function(name) {
        if( this.localStoreSupport() ) {
            localStorage.removeItem(name);
        }
        else {
            this.set(name,"",-1);
        }
    }
}​
Aamir Afridi
la source
4
Pourquoi n'est-ce pas reconnu!? Merci mec!
Robert
4
:) - Je n'aime pas ajouter une bibliothèque entière pour tout ce dont j'ai besoin.
Aamir Afridi
2
est-il permis en JavaScript de définir var expireslocalement et ensuite l'utilisateur dans une autre portée? en fonctionset
happy_marmoset
3
Je voulais juste souligner que tant que vous autorisez la définition d'une expiration sur le cookie, le localStorage n'expirera jamais. Cela pourrait causer des problèmes si vous cherchez quelque chose à expirer. Il peut être avantageux d'inclure l'ajout d'une date d'expiration dans le stockage local, puis de comparer les dates pour voir si elle est toujours applicable. Bien sûr, je dirais également que vous devriez simplement utiliser un cookie si vous avez besoin d'expiration. Mais je pense que ce script devrait soit ne pas autoriser l'expiration, soit l'autoriser, pour les deux, plutôt que d'être incohérent comme il l'est actuellement.
Hanna
1
@MohsinSaeed en mode privé, je pense que le navigateur ne vous permettra pas non plus de créer des cookies. superuser.com/questions/589248/…
Aamir Afridi
19

avez-vous vu la page polyfill sur le wiki Modernizr?

https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills

recherchez la section de stockage Web sur cette page et vous verrez 10 solutions potentielles (en juillet 2011).

bonne chance! marque

Mark Lummus
la source
1
Il semble qu'aucun d'entre eux ne fonctionne en mode Privé / Incognito (par exemple Safari ou Chrome), car leur solution de contournement consiste à créer des cookies, qui sont également désactivés dans ce mode.
Alex Klaus
14

Vous trouverez ci-dessous une version rangée de la réponse d'Aamir Afridi qui conserve tout son code encapsulé dans la portée locale.

J'ai supprimé les références qui créent une retvariable globale et également supprimé l'analyse des chaînes "true" et "false" stockées en valeurs booléennes dans la BrowserStorage.get()méthode, ce qui pourrait poser des problèmes si l'on essaie de stocker les chaînes "true" ou "faux".

Étant donné que l'API de stockage local ne prend en charge que les valeurs de chaîne, il est toujours possible de stocker / récupérer des données de variable JavaScript avec leurs types de données appropriés en codant lesdites données dans une chaîne JSON, qui peut ensuite être décodée à l'aide d'une bibliothèque de codage / décodage JSON telle que https: //github.com/douglascrockford/JSON-js

var BrowserStorage = (function() {
    /**
     * Whether the current browser supports local storage as a way of storing data
     * @var {Boolean}
     */
    var _hasLocalStorageSupport = (function() {
        try {
            return 'localStorage' in window && window['localStorage'] !== null;
        } catch (e) {
            return false;
        }
    })();

    /**
     * @param {String} name The name of the property to read from this document's cookies
     * @return {?String} The specified cookie property's value (or null if it has not been set)
     */
    var _readCookie = function(name) {
        var nameEQ = name + "=";
        var ca = document.cookie.split(';');
        for (var i = 0; i < ca.length; i++) {
            var c = ca[i];
            while (c.charAt(0) == ' ') c = c.substring(1, c.length);
            if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
        }

        return null;
    };

    /**
     * @param {String} name The name of the property to set by writing to a cookie
     * @param {String} value The value to use when setting the specified property
     * @param {int} [days] The number of days until the storage of this item expires
     */
    var _writeCookie = function(name, value, days) {
        var expiration = (function() {
            if (days) {
                var date = new Date();
                date.setTime(date.getTime() + (days*24*60*60*1000));
                return "; expires=" + date.toGMTString();
            }
            else {
                return "";
            }
        })();

        document.cookie = name + "=" + value + expiration + "; path=/";
    };

    return {
        /**
         * @param {String} name The name of the property to set
         * @param {String} value The value to use when setting the specified property
         * @param {int} [days] The number of days until the storage of this item expires (if storage of the provided item must fallback to using cookies)
         */
        set: function(name, value, days) {
            _hasLocalStorageSupport
                ? localStorage.setItem(name, value)
                : _writeCookie(name, value, days);
        },

        /**
         * @param {String} name The name of the value to retrieve
         * @return {?String} The value of the 
         */
        get: function(name) {
            return _hasLocalStorageSupport
                ? localStorage.getItem(name) 
                : _readCookie(name);
        },

        /**
         * @param {String} name The name of the value to delete/remove from storage
         */
        remove: function(name) {
            _hasLocalStorageSupport
                ? localStorage.removeItem(name)
                : this.set(name, "", -1);
        }
    };
})();
Steven
la source
10

Personnellement, je préfère amplify.js . Cela a très bien fonctionné pour moi dans le passé et je l'ai recommandé pour tous les besoins de stockage local.

prend en charge IE 5+, Firefox 2+, Safari 4+, Chrome, Opera 10.5+, iPhone 2+, Android 2+ et fournit une API cohérente pour gérer le stockage entre les navigateurs

raidfive
la source
3

store.js utilise userData et IE et localStorage sur d'autres navigateurs.

  • Il n'essaye pas de faire quelque chose de trop complexe

  • Pas de cookies, pas de flash, pas de jQuery nécessaire.

  • Clean API.

  • 5 ko compressé

https://github.com/marcuswestin/store.js

Mikko Ohtamaa
la source
1

Lawnchair semble aussi être une bonne alternative

une chaise de jardin est un peu comme un canapé, sauf plus petit et à l'extérieur. parfait pour les applications mobiles html5 qui ont besoin d'une solution de persistance légère, adaptative, simple et élégante.

  • collections. une instance de fauteuil de jardin n'est en réalité qu'un tableau d'objets.
  • persistance adaptative. le magasin sous-jacent est abstrait derrière une interface cohérente.
  • comportement de collection enfichable. parfois nous avons besoin d'assistants de collecte mais pas toujours.
j0k
la source
0

Il existe un stockage réel , qui utilise Gears comme solution de secours.

Gaurav
la source
Merci. Malheureusement, il semble qu'il prendrait en charge moins de navigateurs que la suggestion de @ josh3736 de PersistJS. Je vais toujours y jeter un œil et apprécier la suggestion.
Tauren