JavaScript · localStorage

localStorage — projekt zapisywania ustawień użytkownika w JavaScript

setItem, getItem, JSON, licznik odwiedzin i uszkodzone dane w localStorage. Trzy zadania, wyniki i ograniczenia magazynu przeglądarki.

45 minutPoziom podstawowyPliki i rozwiązania

Materiał redakcyjny TablicaPro · liceum i technikum

localStorage.setItem("motyw", "ciemny");
console.log(localStorage.getItem("motyw"));
ciemny
Wartość przetrwa odświeżenie strony.

Zmienne w JavaScript znikają po odświeżeniu strony. Gdy strona ma pamiętać wybrany motyw, rozmiar czcionki albo liczbę odwiedzin, może zapisać dane w przeglądarce użytkownika — w localStorage. Dane przetrwają zamknięcie karty i ponowne uruchomienie przeglądarki. Na lekcji uczniowie zapisują ustawienia jako JSON, liczą odwiedziny i bezpiecznie odczytują dane, które mogły zostać uszkodzone.

Scenariusz jest przeznaczony na 45 minut dla klasy znającej obiekty, JSON i obsługę błędów — na przykład po lekcji o JSON.

Przygotowanie stanowisk

Potrzebna jest przeglądarka z konsolą (F12) i edytor tekstu. Rozpakuj pakiet z sekcji materiałów do osobnego folderu. W folderze start jest index.html (nie zmieniasz go) oraz app.js z funkcją pokaz, która wypisuje tekst w konsoli i na stronie. Po zapisaniu app.js odśwież stronę. Gotowe rozwiązanie jest w folderze rozwiazanie. Serwer i Node.js nie są wymagane.

Cele i plan lekcji

Po zajęciach uczeń potrafi:

  • zapisać i odczytać wartość metodami setItem i getItem;
  • zapisać obiekt jako tekst JSON i odczytać go z powrotem;
  • obsłużyć brak klucza (null) i uszkodzone dane (try/catch);
  • wyjaśnić ograniczenia: tylko teksty, dane widoczne tylko dla jednej strony (źródła) i brak ochrony poufności.
CzasPraca na lekcji
0–5 minProblem: strona po odświeżeniu zapomina motyw
5–15 minsetItem, getItem, removeItem
15–22 minObiekty jako JSON, wartości domyślne
22–37 minTrzy zadania samodzielne
37–42 minOdświeżenie strony i podgląd w narzędziach (Application)
42–45 minPytania kontrolne

Co to jest localStorage

localStorage przechowuje pary klucz–wartość w przeglądarce, osobno dla każdej strony (źródła: adres, protokół i port). Wartości są zawsze tekstami: setItem("odwiedziny", 3) zapisze "3", więc po odczycie trzeba użyć Number. Obiekty zamieniamy na tekst przez JSON.stringify i odczytujemy przez JSON.parse. getItem zwraca null, gdy klucza brak. Metoda removeItem(klucz) usuwa jeden klucz, a clear() — wszystkie klucze strony. Zapisane dane można obejrzeć w narzędziach deweloperskich (zakładka Application lub Storage).

Ostrożność: dane są dostępne dla każdego skryptu na tej stronie i dla użytkownika, więc nie wolno tam trzymać haseł ani danych poufnych. Użytkownik może je usunąć lub zmienić, a odczyt może się nie udać (tryb prywatny, zablokowane dane witryn) — dlatego kod odczytu otaczamy try ... catch i ustawiamy wartość domyślną. W ćwiczeniach z plików otwieranych z dysku (file://) niektóre przeglądarki ograniczają localStorage; w razie problemów uruchom lekcję z lokalnego serwera.

Zadania

Zadanie 1. Ustawienia. Napisz wczytaj() zwracającą ustawienia z localStorage albo wartości domyślne { motyw: "jasny", rozmiar: 16 } i zapisz(ustawienia). Wyczyść magazyn, sprawdź brak klucza, zapisz ustawienia { motyw: "ciemny", rozmiar: 18 } i odczytaj je.

Zadanie 2. Licznik. Napisz odwiedziny(), która zwiększa zapisany licznik o 1 i zwraca nową wartość. Wywołaj ją trzy razy i sprawdź typ zapisanej wartości.

Zadanie 3. Uszkodzone dane. Zapisz pod kluczem ustawień tekst {zepsute, odczytaj ustawienia (funkcja ma zwrócić domyślne), usuń klucz i sprawdź liczbę kluczy.

Dla chętnych: dodaj do ustawień pole jezyk i zadbaj, aby stare zapisane ustawienia bez tego pola dostały wartość domyślną.

Rozwiązanie i wyniki

function pokaz(...czesci) {
  const tekst = czesci.join(" ");
  console.log(tekst);
  document.querySelector("#wynik").textContent += tekst + "\n";
}

const KLUCZ = "ustawienia";
const DOMYSLNE = { motyw: "jasny", rozmiar: 16 };

function wczytaj() {
  try {
    const tekst = localStorage.getItem(KLUCZ);
    return tekst === null ? DOMYSLNE : JSON.parse(tekst);
  } catch (blad) {
    return DOMYSLNE;
  }
}

function zapisz(ustawienia) {
  localStorage.setItem(KLUCZ, JSON.stringify(ustawienia));
}

// Zadanie 1
localStorage.clear();
pokaz(String(localStorage.getItem("brak")), JSON.stringify(wczytaj()));
zapisz({ motyw: "ciemny", rozmiar: 18 });
pokaz(localStorage.getItem(KLUCZ));
pokaz(wczytaj().motyw, wczytaj().rozmiar);

// Zadanie 2
function odwiedziny() {
  const n = Number(localStorage.getItem("odwiedziny") ?? 0) + 1;
  localStorage.setItem("odwiedziny", n);
  return n;
}
pokaz(odwiedziny(), odwiedziny(), odwiedziny());
pokaz(typeof localStorage.getItem("odwiedziny"));

// Zadanie 3
localStorage.setItem(KLUCZ, "{zepsute");
pokaz(JSON.stringify(wczytaj()));
localStorage.removeItem(KLUCZ);
pokaz(String(localStorage.getItem(KLUCZ)), localStorage.length);

Program wypisze:

null {"motyw":"jasny","rozmiar":16}
{"motyw":"ciemny","rozmiar":18}
ciemny 18
1 2 3
string
{"motyw":"jasny","rozmiar":16}
null 1

Typowe błędy

ObjawCo sprawdzić
Licznik wypisuje 01, 011 zamiast 1, 2Wartość z getItem jest tekstem; zamień ją przez Number przed dodawaniem.
[object Object] w magazynieObiekt zapisano bez JSON.stringify.
SyntaxError przy odczycieZapisane dane nie są poprawnym JSON-em; otocz JSON.parse blokiem try ... catch.
Dane nie istnieją na innej stronieMagazyn jest osobny dla każdego źródła (adres, protokół, port).
SecurityError lub brak zapisuTryb prywatny albo zablokowane dane witryn; obsłuż błąd i użyj wartości domyślnych.
clear() usunął za dużoclear() usuwa wszystkie klucze tej strony; do jednego klucza służy removeItem.

Pytania kontrolne i punktacja

  1. Jaki typ mają wartości w localStorage?
  2. Co zwróci getItem("brak"), gdy klucza nie ma?
  3. Dlaczego nie należy tam zapisywać haseł?

Odpowiedzi: Zawsze tekst. null. Bo dane są dostępne dla skryptów strony i dla użytkownika, więc nie są chronione.

Proponowana punktacja (razem 10 punktów): zadanie 1 — wczytaj z wartościami domyślnymi 2 pkt, zapisz z JSON 1 pkt, odczyt zapisanych ustawień 1 pkt; zadanie 2 — licznik z Number 2 pkt, trzy wywołania i typ 1 pkt; zadanie 3 — try/catch 2 pkt, removeItem i liczba kluczy 1 pkt. Zadanie dla chętnych nie jest wymagane do pełnej oceny.

Materiały do pobrania

Rozpakuj ZIP przed otwarciem plików. Materiały są dostępne bez logowania; publiczne rozwiązanie służy nauce i samodzielnemu sprawdzeniu, a nie poufnemu sprawdzianowi.

Co dalej?

Następny krok to ciasteczka, sesje po stronie serwera i podłączenie zapisanych ustawień do wyglądu strony przez DOM. Ten materiał rozwija dział o danych w przeglądarce w kursie JavaScript w TablicaPro, gdzie znajdziesz prezentacje, ćwiczenia i testy do prowadzenia lekcji.

Źródła techniczne: localStorage w MDN oraz Web Storage API. Zobacz też lekcję o DOM w JavaScript.

Poprowadź kolejne lekcje JavaScript

Pełny kurs: prezentacje, ćwiczenia i testy do pracy z klasą.

Kup dostęp do kursu JavaScript →

Zobacz program kursu