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!"
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 |
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 kluczyWeb 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' });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');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'));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}