</> HTML5Advent
ENFRESDEITPT

// apis · Web Platform Advent #6

localStorage vs sessionStorage: a Web Storage API explicada

Quando usar localStorage ou sessionStorage — como diferem em tempo de vida e âmbito, os seus limites de tamanho, como guardar JSON em segurança e reagir ao evento storage.

Um corredor de arquivo estreito ladeado por prateleiras de caixas e dossiês de armazenamento etiquetados

A Web Storage API dá ao navegador dois armazenamentos chave-valor simples — localStorage e sessionStorage — para guardar pequenas quantidades de dados no dispositivo do utilizador. Ambos partilham exatamente a mesma API; diferem apenas em quanto tempo os dados vivem e quem os pode ver.

A API partilhada

Ambos os objetos expõem os mesmos cinco métodos, e ambos guardam apenas strings:

localStorage.setItem('theme', 'dark');
const theme = localStorage.getItem('theme'); // 'dark'
localStorage.removeItem('theme');
localStorage.clear();                          // wipe everything
console.log(localStorage.length);              // number of keys

Ler uma chave que não existe devolve null, por isso pode definir um valor de recurso com ||:

const theme = localStorage.getItem('theme') || 'light';

A única diferença real: o tempo de vida

É toda a decisão numa frase. O localStorage persiste até que o elimine — sobrevive a recarregamentos, fecho de separadores e reinícios do navegador. O sessionStorage vive apenas enquanto existir o separador: feche o separador e os dados desaparecem, e um segundo separador no mesmo site obtém o seu próprio armazenamento separado.

A screen showing colourful JavaScript source code that reads from the window object
Ambos os armazenamentos dependem do objeto global window, por isso localStorage e window.localStorage referem-se exatamente à mesma coisa.

Guardar objetos: stringify e parse

Como o armazenamento só guarda strings, qualquer coisa estruturada tem de passar por JSON. Serialize à entrada, analise à saída:

const user = { name: 'Ada', loggedIn: true };

// Save
localStorage.setItem('user', JSON.stringify(user));

// Read back
const saved = JSON.parse(localStorage.getItem('user'));
console.log(saved.name); // 'Ada'

Envolva JSON.parse num try/catch quando o valor possa estar em falta ou corrompido — analisar null ou texto inválido lança um erro:

function readJSON(key, fallback) {
  try {
    const raw = localStorage.getItem(key);
    return raw ? JSON.parse(raw) : fallback;
  } catch {
    return fallback;
  }
}

Âmbito e o limite de tamanho

O armazenamento está restringido à origem (esquema + host + porta): https://example.com e http://example.com não partilham dados. A quota é de cerca de 5 MB por origem na maioria dos navegadores — generosa para preferências e pequenas caches, mas não uma base de dados. Excedê-la faz com que setItem lance um QuotaExceededError, por isso proteja as escritas de grande dimensão.

Reagir a alterações entre separadores

O evento storage dispara em outros separadores da mesma origem quando o localStorage muda — útil para sincronizar um logout ou uma mudança de tema entre janelas abertas. Note que não dispara no separador que fez a alteração, e o sessionStorage nunca o aciona:

window.addEventListener('storage', (event) => {
  if (event.key === 'theme') {
    applyTheme(event.newValue);
  }
});

Qual deve usar?

localStoragesessionStorage
Tempo de vidaAté ser limpo explicitamenteAté o separador fechar
Partilhado entre separadoresSim (mesma origem)Não (por separador)
Sobrevive ao recarregamentoSimSim
Dispara o evento storageSimNão
Uso típicoTema, definições, "lembrar-me"Rascunhos de formulário pontuais, passos de assistente

Recorra ao localStorage quando os dados devem permanecer entre visitas, e ao sessionStorage quando só fazem sentido para o separador atual. Para qualquer coisa sensível — tokens, palavras-passe, dados pessoais — nenhum é apropriado: ambos são legíveis por qualquer script na página, por isso mantenha os segredos completamente fora do Web Storage.