Soluzioni di riserva per l'archiviazione locale HTML5 [chiuse]


119

Sto cercando librerie javascript e codice che possa simulare localStoragesu browser che non hanno supporto nativo.

Fondamentalmente, mi piacerebbe codificare il mio sito utilizzando localStorageper memorizzare i dati e sapere che funzionerà ancora sui browser che non lo supportano nativamente. Ciò significherebbe che una libreria rileverà se window.localStorageesiste e la utilizzerà se lo fa. Se non esiste, creerebbe una sorta di metodo di fallback di archiviazione locale, creando la propria implementazione nello window.localStoragespazio dei nomi.

Finora ho trovato queste soluzioni:

  1. Implementazione semplice di sessionStorage .
  2. Un'implementazione che utilizza i cookie (non entusiasta di questa idea).
  3. Dojo's dojox.storage , ma è una cosa propria, non proprio un fallback.

Comprendo che Flash e Silverlight possono essere utilizzati anche per l'archiviazione locale, ma non ho trovato nulla sull'utilizzo come riserva per lo standard HTML5 localStorage. Forse anche Google Gears ha questa capacità?

Condividi eventuali librerie, risorse o frammenti di codice correlati che hai trovato! Sarei particolarmente interessato a puro javascript o soluzioni basate su jquery, ma suppongo che sia improbabile.


sessionStorage e localStorage fanno entrambi parte delle specifiche di Web Storage ( dev.w3.org/html5/webstorage ). L'unica differenza è per quanto tempo il browser conserverà i dati. Immagino che non troverai un'implementazione in cui ne hai una ma non l'altra (ma non ne sono sicuro al 100%)
rlovtang

1
Vale la pena ricordare che Gears è stato ufficialmente deprezzato lo scorso febbraio : non ci avrei costruito nulla.
josh3736

@rlovtang: grazie, sono consapevole della differenza tra la sessione e l'archiviazione locale. Secondo l'articolo 24ways.org (primo collegamento in questione, soluzione n. 1), Chrome supporta solo localStorage e non sessionStorage. Forse non è più così, visto che l'articolo è stato scritto tempo fa.
Tauren

@ josh3736: sì, personalmente vorrei evitare di usare cookie e ingranaggi. Certamente non costruirò nulla che dipenda da esso, ma se fosse un meccanismo di archiviazione di riserva per qualcuno che lo aveva installato, e non ci ho programmato direttamente, potrebbe essere usato.
Tauren

quindi in realtà mi sbagliavo :) Non sapevo che Chrome una volta avesse il supporto per localStorage ma non per sessionStorage. Chrome ha il supporto per entrambi almeno ora.
rlovtang

Risposte:


56

Uso PersistJS ( repository github ), che gestisce l'archiviazione lato client in modo trasparente e trasparente per il tuo codice. Utilizzi una singola API e ottieni supporto per i seguenti backend:

  • flash: memoria persistente Flash 8.
  • gears: archiviazione persistente basata su Google Gears.
  • localstorage: archiviazione bozza HTML5.
  • whatwg_db: archiviazione database bozza HTML5.
  • globalstorage: archiviazione bozza HTML5 (vecchia specifica).
  • ad esempio: comportamenti dei dati utente di Internet Explorer.
  • cookie: archiviazione persistente basata su cookie.

Ognuno di questi può essere disabilitato, ad esempio se non si desidera utilizzare i cookie. Con questa libreria, otterrai il supporto nativo per l'archiviazione lato client in IE 5.5+, Firefox 2.0+, Safari 3.1+ e Chrome; e supporto assistito da plug-in se il browser dispone di Flash o Gears. Se abiliti i cookie, funzionerà in tutto (ma sarà limitato a 4 kB).


10
PersistJS è ancora supportato? Mi chiedo come risolva un problema in cui il browser viene aggiornato e il metodo di archiviazione scelto cambia (ad esempio l'archiviazione locale diventa disponibile). La vecchia posizione diventa inaccessibile?
jcalfee314

2
Almeno non sembra più in fase di sviluppo attivo.
Mahn

Questa è una libreria molto audace. Senza alcuna conoscenza delle dimensioni massime nella maggior parte delle tecnologie, dovremmo essere soddisfatti che la nostra app funzioni con molta fortuna ... Anche questa sembra essere solo una soluzione se vuoi risparmiare <64KB.
amico

@julmot Ecco a cosa serve una libreria. Fornisci praticità mentre astrae le cose noiose. Con abbastanza ricerca e tempo, di solito puoi capire come farlo funzionare, indipendentemente dalla dimensione massima. Certo, sembra che l'autore di quel progetto abbia deciso che era troppo ...
William

Sai se funziona con la modalità di navigazione privata di Safari? Attualmente sto riscontrando un problema in cui localStorage non è supportato in Safari Private Browsing sia macOS che iOS.
Austin

61

Polyfill di archiviazione locale semplice basato su JS puro:

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);
        }
    }
}​

4
Perché questo non sta ottenendo riconoscimento !? Grazie uomo!
Robert

4
:) - Non mi piace aggiungere un'intera libreria per tutto ciò di cui ho bisogno.
Aamir Afridi

2
è consentito in JavaScript per definire var expireslocalmente e quindi l'utente in un altro ambito? in funzioneset
happy_marmoset

3
Volevo solo sottolineare che mentre permetti di impostare una scadenza sul cookie, localStorage non scadrà mai. Ciò potrebbe causare alcuni problemi se stai cercando qualcosa che scada. Potrebbe essere utile includere l'aggiunta di una data di scadenza nel localstorage e quindi fare confronti tra date per vedere se è ancora applicabile. Ovviamente direi anche che dovresti usare un cookie se hai bisogno della scadenza. Ma penso che questo script non dovrebbe consentire la scadenza o consentirlo, per entrambi, piuttosto che essere incoerente come lo è attualmente.
Hanna

1
@MohsinSaeed in modalità privata, penso che il browser non ti consentirà di creare cookie. superuser.com/questions/589248/…
Aamir Afridi

19

hai visto la pagina polyfill sul wiki Modernizr?

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

cerca la sezione webstorage in quella pagina e vedrai 10 potenziali soluzioni (a partire da luglio 2011).

in bocca al lupo! marchio


1
Sembra che nessuno di loro funzioni in modalità Privata / Incognito (ad esempio Safari o Chrome), poiché la loro soluzione alternativa è la creazione di cookie, che è disabilitato anche in quella modalità.
Alex Klaus

14

Di seguito è riportata una versione riordinata della risposta di Aamir Afridi che mantiene tutto il suo codice incapsulato all'interno dell'ambito locale.

Ho rimosso i riferimenti che creano una retvariabile globale e ho anche rimosso l'analisi delle stringhe "true" e "false" memorizzate in valori booleani all'interno delBrowserStorage.get() metodo, il che potrebbe causare problemi se si cerca di memorizzare le stringhe "true" o "false".

Poiché l'API di archiviazione locale supporta solo valori stringa, è comunque possibile archiviare / recuperare dati variabili JavaScript insieme ai tipi di dati appropriati codificando tali dati in una stringa JSON, che può quindi essere decodificata utilizzando una libreria di codifica / decodifica JSON come 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);
        }
    };
})();

10

Personalmente preferisco amplify.js . Ha funzionato molto bene per me in passato e l'ho consigliato per tutte le esigenze di archiviazione locale.

supporta IE 5+, Firefox 2+, Safari 4+, Chrome, Opera 10.5+, iPhone 2+, Android 2+ e fornisce un'API coerente per gestire l'archiviazione cross-browser




1

Anche la sedia a sdraio sembra essere una buona alternativa

una sedia a sdraio è una specie di divano, tranne che più piccola e fuori. perfetto per le app mobili html5 che necessitano di una soluzione di persistenza leggera, adattabile, semplice ed elegante.

  • collezioni. un'istanza di un lettino è in realtà solo una serie di oggetti.
  • persistenza adattativa. il negozio sottostante è astratto dietro un'interfaccia coerente.
  • comportamento di raccolta collegabile. a volte abbiamo bisogno di aiutanti nella raccolta, ma non sempre.

0

C'è realstorage , che utilizza Gears come riserva.


Grazie. Sfortunatamente, sembra che supporterebbe meno browser rispetto al suggerimento di PersistJS di @ josh3736. Lo darò ancora un'occhiata e apprezzerò il suggerimento.
Tauren
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.