Utilizando a Storage API do HTML5

Jean Nascimento
em Desenvolvimento

Quando usávamos o HTML4 a única forma de guardar dados no lado do cliente eram os cookies, mas eles não supriam a necessidade que os desenvolvedores possuem de uma interface mais simples de criação e recuperação dos dados. Entretanto, sua maior limitação era o seu tamanho de 4Kb.

Já o HTML5 nos provê três formas de armazenamento de dados no lado do cliente:

  1. sessionStorage;
  2. localStorage;
  3. Web SQL Database.

No quesito suporte dos navegadores, teremos diferenças para a API Storage e Web SQL.

API Storage

IE FIREFOX SAFARI CHROME OPERA IPHONE ANDROID
8.0+ 3.5+ 4.0+ 4.0+ 10.5+ 2.0+ 2.0+

WEB SQL DATABASE

IE FIREFOX SAFARI CHROME OPERA IPHONE ANDROID
4.0+ 4.0+ 10.5+ 3.0+ 2.0+

Analisando as tabelas acima vemos que já podemos utilizar o armazenamento do lado do cliente na maior parte dos navegadores. Contudo, o Firefox ainda peca por não dar suporte ao WebSQL, adicionando suporte ao IndexDB que é um banco de chave:valor.

Nesta primeira etapa veremos o sistema de localStorage e sessionStorage, que fazem parte da API Storage. Seu tipo de armazenamento é de chave: valor, sendo a chave sempre uma STRING. O objeto desta API possui 4 métodos:

  1. getItem(chave) //obtém um valor armazenado no Storage
  2. setItem(chave,valor) //guarda um valor no Storage
  3. removeItem(chave) //exclui um valor do Storage
  4. clear() //limpa o Storage

A diferença entre os dois é que o sessionStorage apenas guarda os dados durante a sessão do usuário, caso ele feche o navegador ou a aba, seus dados são excluídos. Enquanto que o localStorage não possui expiração definida.

Exemplo de utilização:

sessionStorage.setItem('usuario_id',12);
sessionStorage.setItem('usuario_nome','Jean Nascimento');
sessionStorage.setItem('usuario_apelido','suissa');
sessionStorage.setItem('usuario_tema','clean_01');
console.log(sessionStorage);

Também podemos usar a seguinte sintaxe:

sessionStorage[‘usuario_id'] = 12;
sessionStorage['usuario_nome'] = 'Jean Nascimento';
sessionStorage['usuario_apelido'] = 'suissa';
sessionStorage['usuario_tema'] = 'clean_01';

Vamos usar console do Chrome para visualizar os dados.
nX5YrgK3lk6phUGCToMGaA6FyLKObs2gShAOh-ReeuH3Az-3rDArDH6ZLV2vuALcggLdWaDtfO2vijzd3GxdxBv4BR9oK7qe0784thrNYPJyD3ccX9U
eKJkkCPH4auDhC6qrJ6lnL5kv_dqDhOQeGQUomdtivjqdMu3wCsS6WWvfZcFbK6xbGcqoJgpLsCerKXwmCTmniCfrsSG8_hwivggv_4MObhZ3Q6W7Qg

Para recuperarmos nossos valores utilizaremos a função getItem(). Dessa forma, o exemplo mostrando nossos valores fica assim:

document.write('<br />Id: '+sessionStorage.getItem('usuario_id') );
document.write('<br />Nome: '+sessionStorage.getItem('usuario_nome') );
document.write('<br />Apelido: '+sessionStorage.getItem('usuario_apelido') );
document.write('<br />Tema: '+sessionStorage.getItem('usuario_tema') );

O localStorage funciona da mesma forma e com as mesmas funções, entretanto a sua não expiração rápida dos dados é a forma que mais se assemelha aos antigos cookies. E o mais importante é que ele é orientado ao domínio, ou seja, qualquer página que rode no mesmo domínio terá acesso aos dados armazenados. Com este mesmo exemplo posso recuperar os dados em janelas diferentes.
DC_ZxXejeI57pSNxeE-yhTzNmeWiapWwcKJCBEgrylxQTIMqgMCNuhL_2h0JAeZduOD0mll8XtX7NHxkswDEGNxjkPxtlh8DDhnDNhnhk3XQi0nD-0U

Utilizando esta API não conseguiremos armazenar objetos diretamente. Para isso poderemos armazená-lo como uma string em JSON usando a função nativa do javascript:

JSON.stringify(Objeto)

E para recuperarmos, usaremos a função de parse nativa do javascript:

JSON.parse(stringObjeto)

Veja como fica no exemplo abaixo sem a conversão do objeto:

/*estou encapsulando todas as informações
para adicionar o objeto em apenas uma chave. */
var Objeto = { 'usuario_id': 12, 'usuario_nome': 'Jean Nascimento', 'usuario_apelido': 'suissa', 'usuario_tema': 'clean_01' };
//adiciono o Objeto na minha chave testeObjeto.
localStorage.setItem('testeObjeto01', Objeto);
var Objeto_simples = localStorage['testeObjeto'];
console.log('typeof Objeto: ' + typeof Objeto_simples);
console.log('Objeto sem parse: ', Objeto_simples);
console.log('Usuario nome: ', Objeto_simples.usuario_nome);

viLniN-U2py-tZC3-xyGuMutkX_En2wELhcwa1AaEwa_vURN1WvO84_2kEuoBwvnsk4yGr8wWQ7LevHdQCb0NXs4eQlTacWRGOwGd2ePHpJpbI8g0xA

Agora parseando nosso objeto:

localStorage.setItem('testeObjeto02', JSON.stringify(Objeto));
var Objeto_real = localStorage['testeObjeto02'];
var Objeto_json = JSON.parse(Objeto_real)
console.log('typeof Objeto: ' + typeof Objeto_json);
console.log('Objeto: ', Objeto_json);
console.log('Usuario nome: ', Objeto_json.usuario_nome);

-YyfvOQcNvAJOiL2GiNCm-qHpRhdl_Nzc0AREsxwT-_NV1YQXVsMi4dUXTGuPc_aCJgOHbcf_izugghPsDDiAPS4r2qN_n6U4VSUmaiRj0HSNtkb-Aw

Ficará bem mais fácil para trabalharmos com o nosso objeto parseado de forma correta. Com isso, conseguiremos inserir um array de objetos mais facilmente. Veja o exemplo:

//Crio meu array de objetos no formato JSON

var Objetos = [{ 'usuario_id': 12, 'usuario_nome': 'Jean'}, { 'usuario_id': 13, 'usuario_nome': 'Jose'}, { 'usuario_id': 14, 'usuario_nome': 'Joao'}, { 'usuario_id': 15, 'usuario_nome': 'Maria'}];

//limpo meu localStorage

localStorage.clear();

//mostro os objetos

console.log(Objetos);

//salvo em uam variavel o tamanho do nosso array

var tamanho = Objetos.length;

//itero para inserir um objeto por vez

for(var i=0; i<tamanho; i++){

localStorage.setItem('row_'+i, JSON.stringify(Objetos[i]));

}

//mostro as strings gravadas no localStorage

console.log(localStorage);

var Array_objetos = new Array();

for(var i=0; i<tamanho; i++){

Array_objetos[i] = JSON.parse(localStorage.getItem('row_'+i));

}

//mostro os objetos retornados

console.log(Array_objetos);

4JWvoet4RMTQNOwAL3jmoidrimb9Yy815Quhht7DfLe3cauFNbtWG5W47mE1oGYhrCXyEDM01mvZwTFC433sobQoZOEimxL1-zE2pqtsnRNfdC8LDIM

Agora, se não quisermos utilizar este parseamento sempre, poderemos incluir no Prototype da nossa API mais duas funções, já fazendo esta conversão.

Storage.prototype.setObject = function(key, value) {
this.setItem(key, JSON.stringify(value));
}
Storage.prototype.getObject = function(key) {
return this.getItem(key) && JSON.parse(this.getItem(key));
}

Dessa forma, trocaríamos o setItem por setObject e o getItem por getObject. Então teremos o exemplo completo:

var Objetos = [{ 'usuario_id': 12, 'usuario_nome': 'Jean'}, { 'usuario_id': 13, 'usuario_nome': 'Jose'}, { 'usuario_id': 14, 'usuario_nome': 'Joao'}, { 'usuario_id': 15, 'usuario_nome': 'Maria'}];

localStorage.clear();

console.log(Objetos);

var tamanho = Objetos.length;

for(var i=0; i<tamanho; i++){

localStorage.setObject('row_'+i, Objetos[i]);

}

console.log(localStorage);

var Array_objetos = new Array();

for(var i=0; i<tamanho; i++){

Array_objetos[i] = localStorage.getObject('row_'+i);

}

console.log(Array_objetos);

No próximo artigo veremos sobre o Web SQL Database e como usar sqls comuns no lado do cliente.

Até lá!

Mensagem do anunciante:

Em apoio à evangelização do WordPress, os cursos da Apiki são gratuitos para que você possa se especializar na plataforma que mais cresce no mundo. Vagas limitadas, Inscreva-se agora.

Jean Nascimento

é entusiasta da internet desde os 10 anos de idade e trabalha com sites desde os 15. Há cinco é profissional de Desenvolvimento Web, e utiliza xHTML, CSS, jQuery, PHP e Mysql. É evangelista de novas tecnologias como NOSQL e Node.js. Formado pela UTF-PR, faz especialização em Desenvolvimento Web e atualmente trabalha como Webdeveloper Sênior pela WGBNet, além de ser professor pela FAFIT. É criador do blog NosqlBR e contribuinte do MongoBD. http://nosqlbr.com.br

Comentários

Para comentar no iMasters você precisa estar logado.

O iMasters possui mais de 13 mil textos publicados, em 13 anos já somos uma comunidade de mais 350 mil pessoas. Cadastre-se agora mesmo GRATUITAMENTE e tenha acesso a todo o mundo iMasters.

Já tenho conta Quero me cadastrar
  1. Bacana hein Limonada.. é dificil achar pessoas falando features interessantes em HTML5 sem ser coisinhas amadoras e divertidamente nao profissionais como joguinhos, animaçoes e etc. Sem dúvida isso pode prover mais possibilidades na forma que e-commerce e outros sites manipularão cookies..

  2. HTML5 Storage é o que há de melhor. Quem acha ainda que isso ta longe, só ver o quanto o GMail e o Twitter utilizam essa paradinha boa demais.

    Ficou muito bom o artigo, Suissa, Parabéns!

  3. Olá Jean,
    Parabéns pela matéria. Muito bem escrita.
    Apenas um esclarecimento à título de contribuição.
    O Firefox não suporta Web Database Storage por várias razões, entre elas segurança e assim, resolveu implementar a IndexedDB.
    Parece que estava certo, pois o W3C acaba de reconhecer que a tecnologia não é adequada e interrompe a especificação adotando a Indexed Database API em substituição à Web Database Storage.
    http://www.w3.org/TR/2011/WD-IndexedDB-20110419/

    1. Sim sim eu até pensei em fazer um artigo sobre o IndexDB mas acho que só o FF ainda suporte, correto? Mas parece que possa virar padrão neh.

  4. Alô iMasters,
    Sistemas de comentários costumam admitir umas poucas tags HTML (B, I, STRONG, EM, A, …) por padrão ou bloqueiam todas as tags HTML. Sugiro informar ao usuário qual a linha adotada para evitar o que aconteceu com meu comentário.
    Cometi um erro supondo que tudo poderia acontecer menos renderizar tags HTML como texto.

  5. Por que o localStorage não armazena os dados de um input text? Já testei com input hidden e funcionou perfeito, já com o text não. Alguém já passou por isso?

  6. Estou com uma duvida, já que API Storage substitue o cookies, eu posso salvar as senhas dos usuarios na localStorage, para que o usuário não necessite abrir sessão manualmente, sem problemas?

    1. se vc criptografar até poderia mas eu não acho uma boa, voce pode salvar a SESSÃO dele no localStorage assim como o cookie faz, ja que ele não salva sua senha.

Este projeto é mantido e patrocinado pelas empresas: