Utilizziamo i cookie per migliorare la tua esperienza sul sito
CodeWorlds

Web Storage - localStorage i sessionStorage

Dennis Nedry pracuje nad systemem, który musi pamiętać ustawienia użytkownika nawet po zamknięciu przeglądarki. "Nie będę za każdym razem pytał o preferowany widok mapy," mówi. "Web Storage to rozwiązanie!"

Czym jest Web Storage?

Web Storage API udostępnia dwa mechanizmy przechowywania danych w przeglądarce:

| Cecha | localStorage | sessionStorage | |-------|--------------|----------------| | Czas życia | Permanentny (do ręcznego usunięcia) | Do zamknięcia karty/okna | | Zakres | Wszystkie karty tej samej domeny | Tylko bieżąca karta | | Pojemność | ~5-10 MB | ~5-10 MB |

Podstawowe operacje

1// Zapisywanie danych
2localStorage.setItem('lastSector', 'SECTOR-7');
3localStorage.setItem('userName', 'Ray Arnold');
4
5// Odczytywanie danych
6const sector = localStorage.getItem('lastSector');
7console.log(sector); // "SECTOR-7"
8
9// Sprawdzanie czy klucz istnieje
10const theme = localStorage.getItem('theme');
11console.log(theme); // null (jeśli nie istnieje)
12
13// Usuwanie pojedynczego klucza
14localStorage.removeItem('lastSector');
15
16// Czyszczenie całego storage
17localStorage.clear();
18
19// Sprawdzanie liczby zapisanych elementów
20console.log(localStorage.length); // liczba kluczy

Przechowywanie złożonych danych

Web Storage przechowuje tylko stringi. Dla obiektów używamy JSON:

1// ❌ Błąd - obiekt zostanie zamieniony na "[object Object]"
2const dino = { name: 'Rex', species: 'T-Rex' };
3localStorage.setItem('dino', dino);
4console.log(localStorage.getItem('dino')); // "[object Object]"
5
6// ✅ Poprawnie - używamy JSON
7localStorage.setItem('dino', JSON.stringify(dino));
8const retrieved = JSON.parse(localStorage.getItem('dino'));
9console.log(retrieved); // { name: 'Rex', species: 'T-Rex' }
10
11// Bezpieczne pobieranie z domyślną wartością
12function getStoredData(key, defaultValue = null) {
13  try {
14    const item = localStorage.getItem(key);
15    return item ? JSON.parse(item) : defaultValue;
16  } catch (error) {
17    console.error(`Błąd parsowania ${key}:`, error);
18    return defaultValue;
19  }
20}
21
22const settings = getStoredData('userSettings', { theme: 'light', language: 'pl' });

Praktyczne przykłady

1. System preferencji użytkownika

1class UserPreferences {
2  constructor() {
3    this.storageKey = 'jurassicPark_userPrefs';
4    this.defaults = {
5      theme: 'light',
6      language: 'pl',
7      mapView: 'satellite',
8      alertSound: true
9    };
10  }
11
12  load() {
13    try {
14      const stored = localStorage.getItem(this.storageKey);
15      if (stored) {
16        return { ...this.defaults, ...JSON.parse(stored) };
17      }
18    } catch (error) {
19      console.error('Błąd wczytywania preferencji:', error);
20    }
21    return { ...this.defaults };
22  }
23
24  save(preferences) {
25    try {
26      localStorage.setItem(this.storageKey, JSON.stringify(preferences));
27      return true;
28    } catch (error) {
29      console.error('Błąd zapisywania preferencji:', error);
30      return false;
31    }
32  }
33
34  update(key, value) {
35    const prefs = this.load();
36    prefs[key] = value;
37    return this.save(prefs);
38  }
39}
40
41const userPrefs = new UserPreferences();
42const prefs = userPrefs.load();
43userPrefs.update('theme', 'dark');

2. Cache danych offline

1class DataCache {
2  constructor(prefix = 'cache_') {
3    this.prefix = prefix;
4    this.defaultTTL = 5 * 60 * 1000; // 5 minut
5  }
6
7  set(identifier, data, ttl = this.defaultTTL) {
8    const cacheItem = {
9      data: data,
10      cachedAt: Date.now(),
11      expiresAt: Date.now() + ttl
12    };
13
14    try {
15      localStorage.setItem(this.prefix + identifier, JSON.stringify(cacheItem));
16      return true;
17    } catch (error) {
18      return false;
19    }
20  }
21
22  get(identifier) {
23    try {
24      const cached = localStorage.getItem(this.prefix + identifier);
25      if (!cached) return null;
26
27      const cacheItem = JSON.parse(cached);
28
29      // Sprawdź czy nie wygasło
30      if (Date.now() > cacheItem.expiresAt) {
31        localStorage.removeItem(this.prefix + identifier);
32        return null;
33      }
34
35      return cacheItem.data;
36    } catch {
37      return null;
38    }
39  }
40}
41
42const cache = new DataCache('dino_');
43cache.set('trex-001', { name: 'Rex', status: 'active' }, 5 * 60 * 1000);
44console.log(cache.get('trex-001'));

Bezpieczeństwo i dobre praktyki

1// ❌ NIGDY nie przechowuj wrażliwych danych
2localStorage.setItem('password', '123456'); // NIEBEZPIECZNE!
3
4// ✅ Przechowuj tylko niezbędne, niewrażliwe dane
5localStorage.setItem('theme', 'dark'); // OK
6localStorage.setItem('lastVisitedPage', '/dashboard'); // OK
7
8// ✅ Obsługuj błędy (prywatny tryb Safari, pełny storage)
9function safeSetItem(key, value) {
10  try {
11    localStorage.setItem(key, value);
12    return true;
13  } catch (error) {
14    console.error('Nie można zapisać do localStorage:', error);
15    return false;
16  }
17}

Podsumowanie

  1. localStorage - dane permanentne, współdzielone między kartami
  2. sessionStorage - dane tymczasowe, tylko dla bieżącej karty
  3. Tylko stringi - używajcie JSON.stringify/parse dla obiektów
  4. ~5-10 MB limitu - nie przechowujcie dużych plików
  5. Bez wrażliwych danych - to nie jest bezpieczne miejsce!
Vai a CodeWorlds