Fallback-Lösungen für HTML5 Local Storage [geschlossen]

119

Ich suche nach Javascript-Bibliotheken und Code, die localStoragein Browsern ohne native Unterstützung simuliert werden können .

Grundsätzlich möchte ich meine Website localStoragezum Speichern von Daten codieren und wissen, dass sie auch in Browsern funktioniert, die sie nicht nativ unterstützen. Dies würde bedeuten, dass eine Bibliothek window.localStorageerkennt , ob sie vorhanden ist, und sie verwendet, wenn dies der Fall ist. Wenn es nicht vorhanden ist, wird eine Art Fallback-Methode für den lokalen Speicher erstellt, indem eine eigene Implementierung im window.localStorageNamespace erstellt wird.

Bisher habe ich folgende Lösungen gefunden:

  1. Einfache Implementierung von sessionStorage .
  2. Eine Implementierung , die Cookies verwendet (von dieser Idee nicht begeistert).
  3. Dojos dojox.storage , aber es ist seine eigene Sache, nicht wirklich einen Rückfall.

Ich verstehe, dass Flash und Silverlight auch für den lokalen Speicher verwendet werden können, habe aber nichts darüber gefunden, sie als Fallback für Standard-HTML5 localStorage zu verwenden. Vielleicht hat Google Gears diese Funktion auch?

Bitte teilen Sie alle verwandten Bibliotheken, Ressourcen oder Codefragmente, die Sie gefunden haben! Ich würde mich besonders für reine Javascript- oder JQuery-basierte Lösungen interessieren, aber ich denke, das ist unwahrscheinlich.

Tauren
quelle
sessionStorage und localStorage sind beide Teil der Web Storage-Spezifikation ( dev.w3.org/html5/webstorage ). Der einzige Unterschied besteht darin, wie lange der Browser die Daten speichert. Ich denke, Sie werden keine Implementierung finden, in der Sie eine haben, aber nicht die andere (aber ich bin nicht 100% sicher)
rlovtang
1
Es ist erwähnenswert, dass Gears im vergangenen Februar offiziell enteignet wurde - ich würde nichts darauf aufbauen.
Josh3736
@rlovtang: Danke, ich bin mir des Unterschieds zwischen Sitzung und lokalem Speicher bewusst. Laut dem Artikel von 24ways.org (erster fraglicher Link, Lösung Nr. 1) unterstützt Chrome nur localStorage und nicht sessionStorage. Vielleicht ist das nicht mehr der Fall, da dieser Artikel vor einiger Zeit geschrieben wurde.
Tauren
@ josh3736: Ja, ich persönlich möchte die Verwendung von Cookies und Zahnrädern vermeiden. Ich würde sicherlich nichts davon abhängig bauen, aber wenn es ein Fallback-Speichermechanismus für jemanden wäre, der es installiert hat, und ich nicht direkt darauf codiere, könnte es verwendet werden.
Tauren
Ich habe mich also geirrt :) Ich wusste nicht, dass Chrome einmal Unterstützung für localStorage hat, aber nicht für sessionStorage. Chrome unterstützt jetzt zumindest beide.
Rlovtang

Antworten:

56

Ich verwende PersistJS ( Github-Repository ), das den clientseitigen Speicher nahtlos und transparent für Ihren Code verwaltet. Sie verwenden eine einzelne API und erhalten Unterstützung für die folgenden Backends:

  • Flash: Dauerhafter Flash 8-Speicher.
  • Zahnräder: Google Gears-basierter persistenter Speicher.
  • localstorage: HTML5-Entwurfsspeicher.
  • whatwg_db: HTML5-Entwurfsdatenbankspeicher.
  • globalstorage: HTML5-Entwurfsspeicher (alte Spezifikation).
  • dh: Verhalten der Internet Explorer-Benutzerdaten.
  • Cookie: Cookie-basierter persistenter Speicher.

Alle diese Optionen können deaktiviert werden, wenn Sie beispielsweise keine Cookies verwenden möchten. Mit dieser Bibliothek erhalten Sie native clientseitige Speicherunterstützung in IE 5.5+, Firefox 2.0+, Safari 3.1+ und Chrome. und Plugin-unterstützte Unterstützung, wenn der Browser über Flash oder Gears verfügt. Wenn Sie Cookies aktivieren, funktioniert dies in allen Bereichen (ist jedoch auf 4 KB begrenzt).

josh3736
quelle
10
Wird PersistJS noch unterstützt? Ich frage mich, wie es ein Problem löst, bei dem der Browser aktualisiert wird und sich die ausgewählte Speichermethode ändert (z. B. wird lokaler Speicher verfügbar). Wird der alte Standort nicht mehr zugänglich?
jcalfee314
2
Zumindest sieht es nicht mehr so ​​aus, als ob es sich in aktiver Entwicklung befindet.
Mahn
Dies ist eine sehr gewagte Bibliothek. Ohne Kenntnis der maximalen Größe in den meisten Technologien sollten wir uns davon überzeugen, dass unsere App mit viel Glück ausgeführt wird ... Auch dies scheint nur eine Lösung zu sein, wenn Sie <64 KB sparen möchten.
Alter
@ Julmot Dafür ist eine Bibliothek da. Bieten Sie Bequemlichkeit, während Sie die langweiligen Dinge abstrahieren. Mit genügend Recherche und Zeit können Sie normalerweise herausfinden, wie es funktioniert, unabhängig von der maximalen Größe. Natürlich sieht es so aus, als hätte der Autor dieses Projekts entschieden, dass es zu viel war ...
William
Wissen Sie, ob dies mit dem Safari Private Browsing-Modus funktioniert? Derzeit habe ich ein Problem, bei dem localStorage in Safari Private Browsing sowohl für MacOS als auch für iOS nicht unterstützt wird.
Austin
61

Reine JS-basierte einfache localStorage-Polyfüllung:

Demo: 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
quelle
4
Warum wird das nicht anerkannt? Danke, Mann!
Robert
4
:) - Ich mag es nicht, eine komplette Bibliothek für alles hinzuzufügen, was ich brauche.
Aamir Afridi
2
Ist es in JavaScript erlaubt, var expireslokal und dann Benutzer in einem anderen Bereich zu definieren ? in Funktionset
happy_marmoset
3
Ich wollte nur darauf hinweisen, dass der localStorage niemals abläuft, während Sie zulassen, dass ein Ablauf für das Cookie festgelegt wird. Dies kann zu Problemen führen, wenn Sie nach etwas suchen, das abläuft. Es kann nützlich sein, ein Ablaufdatum in den lokalen Speicher aufzunehmen und dann Datumsvergleiche durchzuführen, um festzustellen, ob es noch anwendbar ist. Natürlich würde ich auch argumentieren, dass Sie nur einen Cookie verwenden sollten, wenn Sie einen Ablauf benötigen. Aber ich denke, dieses Skript sollte entweder keinen Ablauf zulassen oder es für beide zulassen, anstatt inkonsistent zu sein, wie es derzeit ist.
Hanna
1
@MohsinSaeed im privaten Modus, ich denke, Browser erlaubt Ihnen nicht, Cookies zu erstellen. superuser.com/questions/589248/…
Aamir Afridi
19

Hast du die Polyfill-Seite im Modernizr-Wiki gesehen?

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

Suchen Sie auf dieser Seite nach dem Abschnitt "Webstorage", und Sie sehen 10 mögliche Lösungen (Stand Juli 2011).

Viel Glück! Kennzeichen

Mark Lummus
quelle
1
Es scheint, dass keiner von ihnen im privaten / inkognito-Modus (z. B. Safari oder Chrome) arbeitet, da ihre Problemumgehung darin besteht, Cookies zu erstellen, die auch in diesem Modus deaktiviert sind.
Alex Klaus
14

Unten finden Sie eine aufgeräumte Version der Antwort von Aamir Afridi, in der der gesamte Code im lokalen Bereich enthalten ist.

Ich habe Referenzen entfernt, die eine globale retVariable erstellen , und auch das Parsen von gespeicherten "true" - und "false" -Strings in boolesche Werte innerhalb der BrowserStorage.get()Methode entfernt, was zu Problemen führen kann, wenn versucht wird, die Strings tatsächlich "true" oder "true" zu speichern "falsch".

Da die lokale Speicher-API nur Zeichenfolgenwerte unterstützt, können JavaScript-Variablendaten zusammen mit den entsprechenden Datentypen gespeichert / abgerufen werden, indem diese Daten in eine JSON-Zeichenfolge codiert werden, die dann mithilfe einer JSON-Codierungs- / Decodierungsbibliothek wie https: decodiert werden kann. //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
quelle
10

Ich persönlich bevorzuge amplify.js . Es hat in der Vergangenheit sehr gut für mich funktioniert und ich habe es für alle lokalen Speicheranforderungen empfohlen.

unterstützt IE 5+, Firefox 2+, Safari 4+, Chrome, Opera 10.5+, iPhone 2+, Android 2+ und bietet eine konsistente API für den browserübergreifenden Speicher

Raidfive
quelle
3

store.js verwendet userData und IE sowie localStorage in anderen Browsern.

  • Es wird nicht versucht, etwas zu Komplexes zu tun

  • Keine Cookies, kein Flash, keine jQuery erforderlich.

  • API bereinigen.

  • 5 kb komprimiert

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

Mikko Ohtamaa
quelle
1

Rasenstuhl scheint auch eine gute Alternative zu sein

Ein Gartenstuhl ist ein bisschen wie eine Couch, nur kleiner und draußen. Perfekt für mobile HTML5-Apps, die eine leichte, anpassungsfähige, einfache und elegante Persistenzlösung benötigen.

  • Sammlungen. Eine Liegestuhlinstanz ist eigentlich nur eine Reihe von Objekten.
  • adaptive Persistenz. Der zugrunde liegende Speicher wird hinter einer konsistenten Schnittstelle abstrahiert.
  • steckbares Erfassungsverhalten. Manchmal brauchen wir Sammlungshelfer, aber nicht immer.
j0k
quelle
0

Es gibt Realstorage , das Gears als Fallback verwendet.

Gaurav
quelle
Vielen Dank. Leider sieht es so aus, als würde es weniger Browser unterstützen als @ josh3736s Vorschlag von PersistJS. Ich werde es mir noch ansehen und den Vorschlag schätzen.
Tauren