Przejdź do treści

~/programowanie cat czym-jest-local-storage-i-jak-uz….md

Local Storage — co to jest i jak używać localStorage w JavaScript

Local storage co to: pamięć przeglądarki typu klucz–wartość. Metody setItem i getItem, zapis obiektów w JSON, limity, bezpieczeństwo i porównanie z cookies.

CZCzarek Zawolski--aktualizacja=--czas=7 min--dział=Programowanie i bazy danych
Ilustracja danych zapisywanych w pamięci przeglądarki internetowej
tldr.txt — W skrócie

~ xad tldr czym-jest-local-storage-i-…

  • localStorage to magazyn klucz–wartość w przeglądarce, przypisany do jednego originu (protokół + domena + port); dane nie wygasają same.
  • Podstawowe metody: setItem, getItem, removeItem, clear, key i właściwość length.
  • Przechowuje wyłącznie tekst — obiekty i tablice zapisuj przez JSON.stringify, a odczytuj przez JSON.parse.
  • Limit to zwykle około 5 MB na origin; po jego przekroczeniu zapis rzuca wyjątek QuotaExceededError.
  • Nie trzymaj w localStorage haseł ani tokenów sesji — każdy skrypt na stronie (także wstrzyknięty przez XSS) może je odczytać.
$ tree --spis-tresci

Local Storage (w kodzie: localStorage) to pamięć przeglądarki, w której strona może zapisać dane w postaci par klucz–wartość. Dane są przypisane do konkretnej witryny, nie wygasają same i przetrwają zamknięcie karty, przeglądarki, a nawet restart komputera. Obsługują go wszystkie współczesne przeglądarki.

Typowe zastosowania to zapamiętanie motywu (jasny/ciemny), języka, zawartości koszyka w prostym sklepie czy szkicu formularza. Poniżej znajdziesz pełne API z przykładami, ograniczenia, zasady bezpieczeństwa i porównanie z sessionStorage, cookies oraz IndexedDB.

Local storage — co to jest i jak działa

localStorage jest częścią standardu Web Storage (dziś opisanego w specyfikacji HTML). Każda strona dostaje własny, odizolowany magazyn przypisany do originu, czyli kombinacji:

  • protokołu (https vs http),
  • domeny (sklep.example.com to inny origin niż example.com),
  • portu (localhost:3000 i localhost:5173 mają osobne magazyny).

Strona nie ma dostępu do localStorage innych stron, a serwer nie widzi tych danych — w odróżnieniu od cookies nie są one dołączane do żądań HTTP. Jeśli chcesz coś wysłać na serwer, robisz to samodzielnie, np. przez fetch() (więcej o komunikacji z backendem w poradniku o REST API).

Trzy cechy, o których trzeba pamiętać od początku:

  1. Przechowuje tylko ciągi znaków. Liczba 5 zapisze się jako "5", a obiekt bez konwersji jako bezużyteczne "[object Object]".
  2. Działa synchronicznie — każde wywołanie blokuje główny wątek, dopóki przeglądarka nie odczyta lub nie zapisze danych.
  3. Nie ma daty ważności. Dane znikają dopiero, gdy usunie je kod strony, użytkownik albo przeglądarka (np. przy braku miejsca na dysku lub po zamknięciu okna prywatnego).

Metody localStorage: setItem, getItem, removeItem, clear

Obiekt localStorage implementuje interfejs Storage. Oto wszystkie jego metody:

// zapis wartości pod kluczem
localStorage.setItem('motyw', 'ciemny');

// odczyt — zwraca string albo null, gdy klucza nie ma
const motyw = localStorage.getItem('motyw'); // "ciemny"

// usunięcie jednego klucza
localStorage.removeItem('motyw');

// usunięcie wszystkich danych tej strony
localStorage.clear();

// liczba zapisanych kluczy i nazwa klucza o danym indeksie
console.log(localStorage.length);
console.log(localStorage.key(0));

Preferencje zapisane po stronie przeglądarki zachowują się wszędzie podobnie: obowiązują tylko w tej jednej przeglądarce i znikają po wyczyszczeniu danych witryny. Dobrze to widać np. na tiktok.com, gdzie ciemny motyw trzeba włączyć osobno w każdej przeglądarce — opisujemy to w poradniku jak ustawić czarnego TikToka.

Można też używać składni obiektowej (localStorage.motyw = 'ciemny'), ale nie jest to zalecane. Klucz o nazwie takiej jak wbudowana metoda (np. key czy length) nie zadziała poprawnie, a getItem jasno zwraca null dla brakującego klucza, zamiast undefined.

Żeby przejrzeć wszystkie zapisane pary, iteruj po indeksach:

for (let i = 0; i < localStorage.length; i++) {
  const klucz = localStorage.key(i);
  console.log(klucz, localStorage.getItem(klucz));
}

Zapisywanie obiektów i tablic przez JSON

Ponieważ localStorage przyjmuje tylko tekst, dane złożone serializuje się do JSON:

const koszyk = [
  { id: 17, nazwa: 'Kabel HDMI', ilosc: 2 },
  { id: 42, nazwa: 'Router', ilosc: 1 }
];

localStorage.setItem('koszyk', JSON.stringify(koszyk));

const zapisany = JSON.parse(localStorage.getItem('koszyk') ?? '[]');
console.log(zapisany[0].nazwa); // "Kabel HDMI"

Operator ?? '[]' zabezpiecza przed sytuacją, w której klucza nie ma — JSON.parse(null) zwróci null, a próba odczytu zapisany[0] zakończy się błędem. Pamiętaj też, że JSON nie przenosi wszystkiego: obiekty Date zamienią się w tekst, a Map, Set i funkcje zostaną utracone.

W praktyce warto owinąć localStorage prostymi funkcjami pomocniczymi, które obsłużą błędy parsowania i brak dostępu do magazynu:

function zapisz(klucz, wartosc) {
  try {
    localStorage.setItem(klucz, JSON.stringify(wartosc));
    return true;
  } catch (e) {
    // QuotaExceededError, zablokowany magazyn itp.
    console.warn('Nie udało się zapisać', klucz, e);
    return false;
  }
}

function odczytaj(klucz, domyslna = null) {
  try {
    const surowe = localStorage.getItem(klucz);
    return surowe === null ? domyslna : JSON.parse(surowe);
  } catch {
    return domyslna;
  }
}

Blok try/catch nie jest przesadną ostrożnością. Dostęp do localStorage może rzucić wyjątek, gdy użytkownik zablokował dane witryn w ustawieniach, gdy strona działa w ramce z restrykcjami albo gdy skończy się limit miejsca.

Dane z datą ważności i synchronizacja między kartami

localStorage nie ma wbudowanego wygasania, ale łatwo je dodać, zapisując razem z wartością znacznik czasu:

function zapiszNa(klucz, wartosc, minuty) {
  const wpis = { wartosc, wygasa: Date.now() + minuty * 60_000 };
  localStorage.setItem(klucz, JSON.stringify(wpis));
}

function odczytajWazne(klucz) {
  const wpis = JSON.parse(localStorage.getItem(klucz) ?? 'null');
  if (!wpis) return null;
  if (Date.now() > wpis.wygasa) {
    localStorage.removeItem(klucz);
    return null;
  }
  return wpis.wartosc;
}

Gdy jedna karta zmieni dane, pozostałe karty tej samej strony dostają zdarzenie storage. Pozwala to np. wylogować użytkownika we wszystkich kartach naraz albo odświeżyć licznik koszyka:

window.addEventListener('storage', (event) => {
  if (event.key === 'koszyk') {
    const nowy = JSON.parse(event.newValue ?? '[]');
    odswiezLicznik(nowy.length);
  }
});

Zdarzenie nie jest wywoływane w karcie, która dokonała zmiany — tylko w pozostałych. Do bardziej rozbudowanej komunikacji między kartami lepiej nadaje się BroadcastChannel.

Limity i ograniczenia localStorage

CechaJak to wygląda w praktyce
PojemnośćZwykle ok. 5 MB na origin (Chrome, Edge, Firefox, Safari); standard nie ustala dokładnej wartości
Typ danychTylko string; resztę trzeba serializować
WydajnośćOperacje synchroniczne; duże zapisy mogą przycinać interfejs
DostępnośćTylko w głównym wątku — nie ma go w Web Workerach ani Service Workerach
Tryb prywatnyDziała, ale dane są kasowane po zamknięciu okien prywatnych
SafariMechanizm ITP może usunąć dane zapisane skryptem, jeśli użytkownik nie odwiedzał strony przez 7 dni

Po przekroczeniu limitu setItem rzuca DOMException o nazwie QuotaExceededError. Jeśli potrzebujesz więcej miejsca albo przechowujesz pliki, obrazy lub tysiące rekordów, sięgnij po IndexedDB — asynchroniczną bazę w przeglądarce z limitami liczonymi w setkach megabajtów lub więcej, zależnie od wolnego miejsca na dysku.

Bezpieczeństwo: czego nie zapisywać w localStorage

localStorage nie jest szyfrowany i nie ma żadnej kontroli dostępu poza izolacją originu. Każdy skrypt uruchomiony na stronie — Twój, z biblioteki zewnętrznej, z widżetu reklamowego albo wstrzyknięty przez atakującego — może odczytać cały magazyn jedną linijką kodu.

Uwaga: Nie przechowuj w localStorage haseł, danych kart płatniczych, danych osobowych ani tokenów uwierzytelniających (np. JWT z długim czasem życia). Jedna podatność Cross-Site Scripting wystarczy, żeby atakujący wysłał je na swój serwer i przejął sesję użytkownika.

Tokeny sesyjne bezpieczniej trzymać w ciasteczkach z flagami HttpOnly, Secure i SameSite — HttpOnly sprawia, że JavaScript w ogóle ich nie widzi. Trzeba wtedy zadbać o ochronę przed atakami CSRF, ale to problem łatwiejszy do opanowania niż kradzież tokenu. Więcej o skutkach przejęcia sesji przeczytasz w tekście o session hijacking.

Druga sprawa to prywatność. Przepisy o przechowywaniu informacji na urządzeniu użytkownika dotyczą nie tylko cookies, ale każdego takiego mechanizmu. Jeśli zapisujesz w localStorage identyfikatory do analityki lub marketingu, potrzebujesz zgody tak samo jak przy ciasteczkach — patrz poradnik o Google Consent Mode v2. Dane niezbędne do działania strony (np. zawartość koszyka, wybrany motyw) zwykle zgody nie wymagają.

localStorage, sessionStorage, cookies czy IndexedDB?

localStoragesessionStorageCookiesIndexedDB
Czas życiaDo usunięciaDo zamknięcia kartyDo daty wygaśnięcia lub końca sesjiDo usunięcia
ZasięgWszystkie karty originuJedna kartaDomena i ścieżkaWszystkie karty originu
Pojemnośćok. 5 MBok. 5 MBok. 4 KB na ciasteczkoSetki MB i więcej
Wysyłane do serweraNieNieTak, z każdym żądaniemNie
APISynchroniczne, prosteSynchroniczne, prostedocument.cookie lub nagłówki HTTPAsynchroniczne, złożone
Dobre doPreferencji, cache, szkicówStanu jednego formularza lub kreatoraSesji i uwierzytelnianiaDużych zbiorów danych, trybu offline

Prosta reguła: preferencje i niewielkie dane interfejsu — localStorage; stan tylko na czas wizyty w jednej karcie — sessionStorage; uwierzytelnianie — ciasteczka HttpOnly; dużo danych lub aplikacja offline — IndexedDB (najlepiej przez bibliotekę typu idb lub Dexie).

Jak podejrzeć i wyczyścić localStorage w przeglądarce

Podczas pracy nad stroną najwygodniej korzystać z narzędzi deweloperskich:

  1. Chrome, Edge, Opera: naciśnij F12 → karta Application → w lewym panelu Storage → Local storage → wybierz adres strony. Wpisy możesz edytować dwuklikiem, a ikoną z przekreślonym kółkiem wyczyścić wszystko.
  2. Firefox: F12 → karta Storage → Local Storage.
  3. Safari: włącz menu Programowanie w ustawieniach zaawansowanych, potem Programowanie → Pokaż inspektora www → karta Storage.

Z konsoli możesz też wyświetlić całą zawartość jednym poleceniem:

console.table(Object.entries(localStorage));

Zwykły użytkownik, który chce usunąć dane jednej strony, zrobi to w ustawieniach przeglądarki: w Chrome Ustawienia → Prywatność i bezpieczeństwo → Ustawienia witryn → Wyświetl uprawnienia i dane przechowywane na stronach, a następnie usuwa dane wybranej witryny. Wyczyszczenie „plików cookie i danych witryn” w historii usuwa także localStorage.

Dobre praktyki na koniec

  • Nadawaj kluczom prefiks aplikacji (np. mojaapp:motyw), żeby uniknąć kolizji ze skryptami zewnętrznymi na tej samej domenie.
  • Zapisuj numer wersji struktury danych — po zmianie formatu łatwo wykryjesz stare wpisy i je zmigrujesz.
  • Zawsze obsługuj brak danych i wyjątki; aplikacja musi działać także z pustym magazynem.
  • Traktuj localStorage jak cache, a nie źródło prawdy: wszystko, co ważne, powinno być też na serwerze.
  • Nie zapisuj dużych obiektów przy każdym naciśnięciu klawisza — użyj debounce, bo zapis jest synchroniczny.

~ man faq

Najczęściej zadawane pytania

Local storage co to jest?

To wbudowany w przeglądarkę mechanizm Web Storage, który pozwala stronie zapisać pary klucz–wartość na komputerze użytkownika. Dane zostają po zamknięciu karty i przeglądarki, dopóki strona lub użytkownik ich nie usunie.

Ile danych zmieści localStorage?

W popularnych przeglądarkach około 5 MB na origin, czyli na kombinację protokołu, domeny i portu. Limit nie jest ustalony w standardzie, więc nie projektuj aplikacji na styk.

Czym różni się localStorage od sessionStorage?

API jest identyczne, ale sessionStorage żyje tylko w obrębie jednej karty i znika po jej zamknięciu. localStorage jest wspólny dla wszystkich kart tej samej strony i przetrwa restart przeglądarki.

Czy localStorage jest bezpieczny?

Nie nadaje się do danych wrażliwych. Nie jest szyfrowany, a dostęp ma każdy skrypt JavaScript działający na stronie, więc atak XSS pozwala go w całości odczytać.

Jak wyczyścić localStorage w przeglądarce?

W Chrome i Edge otwórz narzędzia deweloperskie (F12), kartę Application, sekcję Local storage i usuń wpisy. Możesz też usunąć dane witryny w ustawieniach prywatności przeglądarki albo wywołać localStorage.clear() w konsoli.

Ten artykuł jest częścią tematu

CZ

$ whoami

Czarek Zawolski

Założyciel i redaktor XAD.pl. Pisze o sieciach, bezpieczeństwie IT, administracji systemami Windows i Linux oraz o sprzęcie, który sprawia ludziom problemy na co dzień.

~ ls ../podobne