Seções iMasters
Desenvolvimento + HTML

Utilizando a Storage API do HTML5

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:

Torne-se um Parceiro de Software Intel®. Filie-se ao Intel® Developer Zone. Intel®Developer Zone

Comente também

33 Comentários

Rinaldi Fonseca Nascimento

Muito bom, parabéns!

Ana Cláudia de Araújo

Os Artigos do site são excelentes! ;)

Jean Nascimento

Muito obrigado!

Juarez

Piá, legal teu artigo!!!! Parabéns!!! Só faltou alguns palavrões para completar :)

    Jean Nascimento

    Só falo palavrão no podcast para dar uma descontraída ehhehhee

tiburcio

show mininu

Jean Nascimento

Vamos ver se sai uma série de artigos sobre html5 ;D

James

Ótimo artigo Jean, parabéns!

Hericson Ramos Forti

Muito bom … como sempre Suissa com otimos artigos e com belos exemplos!

Norberto Oliveira Junior

Cada vez melhor hein manolo. Você é um F5 em forma de pessoa. ahahha

    Jean Nascimento

    ahuhahuahuHUahua melhor frase EVER! Isso deveria até virar minha BIO no twitter =p

Luiz Tiago Oliveira

Muito legal, cara!
Local storage é coisa linda de @OCriador!

    Jean Nascimento

    E eu empolgado com o WebSQL e a w3c tira isso de mim :___(

Andre

Muito bom o artigo hein! Parabéns aih…e faz mesmo a série de artigo do html5, com ctza vou acompanhá-las haha

    Jean Nascimento

    Deixa comigo pois esta é uma área que muitoooooo me interessa.

Bernard De Luna

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..

Leo Balter

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!

Igor

se vcs conhecessem ele, teriam medo dos artigos!
bboooom!

Guilherme Guimarães

Parabéns pelo artigo Jean!
Ficou ótimo, direto e fácil de entender!

Abraço!

Leandro Santos

ótimo Post, era justamente isso que estava procurando!

Jonatan

Se fosse .net era legal.

Maujor

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/

    Jean Nascimento

    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.

Maujor

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.

Leandro Santos

Mestre Maujor, Sempre tirando dúvidas e esclarecendo mais ainda nos conteúdo Web!!

Jean Nascimento

Pior que meu artigo de WebSQL ja estava em 90% até meu CRUD em js, agora terei que acrescentar o IndexedDB nos 2.

http://hacks.mozilla.org/2010/06/comparing-indexeddb-and-webdatabase/

Augusto Santos

Bom trabalho.

Alex

Façam o que o Maujor indicou para ser feito. ¬¬

Wellington

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?

willian

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?

    Jean Nascimento

    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.

Qual a sua opinião?