Soluções substitutas de armazenamento local HTML5 [fechadas]

119

Estou procurando bibliotecas javascript e código que possa simular localStorageem navegadores que não têm suporte nativo.

Basicamente, gostaria de codificar meu site localStoragepara armazenar dados e saber que ele ainda funcionará em navegadores que não os suportam nativamente. Isso significaria que uma biblioteca detectaria se existiria window.localStoragee usaria se existir. Se não existir, criaria algum tipo de método de fallback de armazenamento local, criando sua própria implementação no window.localStorageespaço para nome.

Até agora, encontrei estas soluções:

  1. Implementação simples sessionStorage .
  2. Uma implementação que usa cookies (não se emociona com essa ideia).
  3. Dojox.storage do Dojo , mas é coisa própria, não é realmente um substituto.

Entendo que o Flash e o Silverlight também podem ser usados ​​para armazenamento local, mas não encontrei nada sobre como usá-los como substituto do localStorage HTML5 padrão. Talvez o Google Gears também tenha esse recurso?

Compartilhe as bibliotecas, recursos ou snippets de código relacionados que você encontrou! Eu estaria especialmente interessado em javascript puro ou soluções baseadas em jquery, mas acho que isso é improvável.

Tauren
fonte
sessionStorage e localStorage fazem parte da especificação do Armazenamento na Web ( dev.w3.org/html5/webstorage ). A única diferença é quanto tempo o navegador manterá os dados. Eu acho que você não vai encontrar uma implementação onde você tem um, mas não o outro (mas não tenho 100% de certeza)
rlovtang
1
Vale ressaltar que o Gears foi oficialmente depreciado em fevereiro passado - eu não construiria nada sobre isso.
precisa saber é o seguinte
@rlovtang: obrigado, estou ciente da diferença entre a sessão e o armazenamento local. De acordo com o artigo 24ways.org (primeiro link em questão, solução 1), o Chrome suporta apenas localStorage e não sessionStorage. Talvez esse não seja mais o caso, como esse artigo foi escrito há um tempo atrás.
Tauren 15/01
@ josh3736: sim, eu pessoalmente gostaria de evitar o uso de cookies e engrenagens. Eu certamente não criaria nada dependente dele, mas se fosse um mecanismo de armazenamento de fallback para alguém que o tivesse instalado e eu não codificasse diretamente, ele poderia ser usado.
Tauren 15/01
então eu estava realmente errado :) Não sabia que o Chrome já tinha suporte para localStorage, mas não sessionStorage. O Chrome tem suporte para os dois agora, pelo menos.
rlovtang

Respostas:

56

Eu uso o PersistJS ( repositório github ), que lida com o armazenamento do lado do cliente de maneira perfeita e transparente ao seu código. Você usa uma única API e obtém suporte para os seguintes back-end:

  • flash: armazenamento persistente do Flash 8.
  • engrenagens: armazenamento persistente baseado no Google Gears.
  • localstorage: armazenamento de rascunho em HTML5.
  • whatwg_db: armazenamento de banco de dados de rascunho em HTML5.
  • globalstorage: armazenamento de rascunho em HTML5 (especificação antiga).
  • ou seja: comportamentos de dados do usuário do Internet Explorer.
  • cookie: armazenamento persistente baseado em cookie.

Qualquer uma dessas opções pode ser desativada - se, por exemplo, você não deseja usar cookies. Com esta biblioteca, você obterá suporte de armazenamento nativo do lado do cliente no IE 5.5+, Firefox 2.0+, Safari 3.1+ e Chrome; e suporte assistido por plug-in se o navegador tiver Flash ou Gears. Se você ativar os cookies, ele funcionará em tudo (mas será limitado a 4 kB).

josh3736
fonte
10
O PersistJS ainda é suportado? Gostaria de saber como ele resolve um problema em que o navegador é atualizado e o método de armazenamento escolhido muda (digamos, o armazenamento local fica disponível). O local antigo fica acessível?
jcalfee314
2
Pelo menos, não parece mais estar em desenvolvimento ativo.
Mahn
Esta é uma biblioteca muito ousada. Sem nenhum conhecimento sobre o tamanho máximo na maioria das tecnologias, devemos saber que nosso aplicativo é executado com muita sorte ... Além disso, isso parece ser apenas uma solução se você deseja economizar <64 KB.
cara
@julmot É para isso que serve uma biblioteca. Ofereça comodidade enquanto abstrai as coisas tediosas. Com bastante pesquisa e tempo, você geralmente pode descobrir como fazê-lo funcionar, independentemente do tamanho máximo. Claro, parece que o autor desse projeto decidiu que era demais ...
William
Você sabe se isso funciona com o modo de Navegação Privada Safari? No momento, estou tendo um problema em que o localStorage não é suportado na Navegação privada do Safari, tanto no macOS quanto no iOS.
Austin
61

Polyfill localStorage simples baseado em JS puro:

Demonstração: 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
fonte
4
Por que isso não está sendo reconhecido? Valeu cara!
Robert
4
:) - Não gosto de adicionar uma biblioteca inteira para tudo o que preciso.
Aamir Afridi
2
é permitido no JavaScript definir var expireslocalmente e depois o usuário em outro escopo? em funçãoset
happy_marmoset 12/11/2013
3
Só queria ressaltar que, enquanto você permite que uma expiração seja definida no cookie, o localStorage nunca expirará. Isso pode causar alguns problemas se você estiver procurando algo para expirar. Pode ser benéfico incluir a adição de uma data de validade no armazenamento local e fazer comparações de datas para verificar se ainda é aplicável. É claro que eu também argumentaria que você deve usar um cookie se precisar de vencimento. Mas acho que esse script não deve permitir a expiração ou permitir, para ambos, em vez de ser inconsistente como atualmente.
Hanna
1
@MohsinSaeed em modo privado, acho que o navegador também não permitirá que você crie cookies. superuser.com/questions/589248/...
Aamir Afridi
19

você viu a página polyfill no wiki Modernizr?

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

procure a seção de armazenamento na web nessa página e verá 10 soluções em potencial (a partir de julho de 2011).

boa sorte! Marca

Mark Lummus
fonte
1
Parece que nenhum deles está funcionando no modo Privado / de Navegação Anônima (por exemplo, Safari ou Chrome), pois sua solução alternativa está criando cookies, que também são desativados nesse modo.
Alex Klaus
14

Abaixo está uma versão ordenada da resposta de Aamir Afridi que mantém todo o seu código encapsulado no escopo local.

Eu removi referências que criam uma retvariável global e também removemos a análise de seqüências armazenadas "true" e "false" em valores booleanos dentro do BrowserStorage.get()método, o que poderia causar problemas se alguém estivesse tentando armazenar as seqüências "true" ou "falso".

Como a API de armazenamento local suporta apenas valores de cadeia, ainda é possível armazenar / recuperar dados variáveis ​​de JavaScript junto com seus tipos de dados apropriados, codificando esses dados em uma cadeia JSON, que pode ser decodificada usando uma biblioteca de codificação / decodificação JSON, como 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
fonte
10

Eu pessoalmente prefiro amplify.js . Ele funcionou muito bem para mim no passado e eu o recomendei para todas as necessidades de armazenamento local.

suporta IE 5+, Firefox 2+, Safari 4+, Chrome, Opera 10.5+, iPhone 2+, Android 2+ e fornece uma API consistente para lidar com armazenamento entre navegadores

raidfive
fonte
3

O store.js usa userData e IE e localStorage em outros navegadores.

  • Ele não tenta fazer algo muito complexo

  • Sem cookies, sem flash, sem jQuery necessário.

  • API limpa.

  • 5 kb comprimido

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

Mikko Ohtamaa
fonte
1

Lawnchair parece ser uma boa alternativa também

uma cadeira de jardim é como um sofá, exceto menor e do lado de fora. perfeito para aplicativos móveis html5 que precisam de uma solução de persistência leve, adaptável, simples e elegante.

  • coleções. uma instância de cadeira de gramado é realmente apenas uma variedade de objetos.
  • persistência adaptativa. o armazenamento subjacente é abstraído por trás de uma interface consistente.
  • comportamento de coleção conectável. às vezes precisamos de ajudantes de coleta, mas nem sempre.
j0k
fonte
0

armazenamento real , que usa o Gears como substituto.

Gaurav
fonte
Obrigado. Infelizmente, parece que ele suportaria menos navegadores do que a sugestão de PersistJS do @ josh3736. Ainda vou dar uma olhada e apreciar a sugestão.
Tauren 15/01