Anfänger202025-01-15

JavaScript Storage API - LocalStorage & SessionStorage

Lerne wie du Daten im Browser speicherst mit LocalStorage und SessionStorage. Inklusive praktischer Beispiele für Themes, Shopping Carts und mehr.

#javascript#localstorage#sessionstorage#browser#storage

JavaScript Storage API

Mit der Web Storage API kannst du Daten direkt im Browser speichern - ohne Datenbank oder Server!

LocalStorage vs SessionStorage

Unterschiede im Überblick
// LocalStorage - Daten bleiben DAUERHAFT gespeichert
localStorage.setItem('theme', 'dark');
// ✅ Bleibt auch nach Browser-Neustart!

// SessionStorage - Daten nur für diese SESSION
sessionStorage.setItem('temp', 'value');
// ❌ Weg nach Tab-Schließen!

// Unterschiede:
// LocalStorage:
// - Speichert dauerhaft (kein Ablaufdatum)
// - Verfügbar in allen Tabs/Fenstern der gleichen Domain
// - ~5-10 MB Speicher

// SessionStorage:
// - Nur für aktuelle Browser-Session
// - Nur im aktuellen Tab verfügbar
// - Weg nach Tab schließen
// - ~5-10 MB Speicher

LocalStorage - Die Basics

Daten speichern und lesen

setItem() & getItem()
// Daten speichern
localStorage.setItem('username', 'Anna');
localStorage.setItem('age', '25');
localStorage.setItem('isLoggedIn', 'true');

// Daten lesen
const username = localStorage.getItem('username');
console.log(username); // 'Anna'

const age = localStorage.getItem('age');
console.log(age); // '25' (String!)

// Nicht vorhanden → null
const email = localStorage.getItem('email');
console.log(email); // null

Daten löschen

removeItem() & clear()
// Einzelnes Item löschen
localStorage.removeItem('username');

// Alles löschen
localStorage.clear();

// Prüfen ob vorhanden
if (localStorage.getItem('username')) {
  console.log('User ist eingeloggt');
} else {
  console.log('User ist ausgeloggt');
}

Objekte speichern mit JSON

Wichtig: LocalStorage speichert nur Strings! Für Objekte: JSON verwenden.

Objekte speichern
const user = {
  name: 'Anna',
  age: 25,
  email: 'anna@example.com',
  preferences: {
    theme: 'dark',
    language: 'de'
  }
};

// ❌ FALSCH - Objekt direkt speichern
localStorage.setItem('user', user);
console.log(localStorage.getItem('user')); // '[object Object]' ❌

// ✅ RICHTIG - Mit JSON.stringify()
localStorage.setItem('user', JSON.stringify(user));

// Wieder auslesen mit JSON.parse()
const savedUser = JSON.parse(localStorage.getItem('user'));
console.log(savedUser);
// { name: 'Anna', age: 25, email: '...', preferences: {...} } ✅

Helper-Funktionen für einfacheres Handling

Storage Helper Functions
// Hilfsfunktionen für einfacheres Arbeiten
const storage = {
  // Speichern (automatisch JSON)
  set(key, value) {
    try {
      localStorage.setItem(key, JSON.stringify(value));
      return true;
    } catch (error) {
      console.error('Storage Error:', error);
      return false;
    }
  },

  // Laden (automatisch JSON parse)
  get(key, defaultValue = null) {
    try {
      const item = localStorage.getItem(key);
      return item ? JSON.parse(item) : defaultValue;
    } catch (error) {
      console.error('Parse Error:', error);
      return defaultValue;
    }
  },

  // Löschen
  remove(key) {
    localStorage.removeItem(key);
  },

  // Alles löschen
  clear() {
    localStorage.clear();
  }
};

// Verwenden
storage.set('user', { name: 'Anna', age: 25 });
const user = storage.get('user');
console.log(user); // { name: 'Anna', age: 25 }

storage.remove('user');

Praktische Beispiele

Beispiel 1: Dark Mode speichern

Theme Switcher mit LocalStorage
// Theme beim Laden anwenden
function initTheme() {
  // Gespeichertes Theme laden
  const savedTheme = localStorage.getItem('theme') || 'light';

  // Theme anwenden
  document.body.classList.toggle('dark-mode', savedTheme === 'dark');
}

// Theme wechseln
function toggleTheme() {
  const isDark = document.body.classList.toggle('dark-mode');
  const theme = isDark ? 'dark' : 'light';

  // Theme speichern
  localStorage.setItem('theme', theme);

  console.log(`Theme gewechselt zu: ${theme}`);
}

// Beim Laden initialisieren
initTheme();

// Button Event
document.getElementById('theme-toggle').addEventListener('click', toggleTheme);

Beispiel 2: Form-Daten automatisch speichern

Auto-Save Form
const form = document.getElementById('contact-form');
const STORAGE_KEY = 'form_draft';

// Form-Daten laden
function loadFormData() {
  const savedData = localStorage.getItem(STORAGE_KEY);

  if (savedData) {
    const data = JSON.parse(savedData);

    // Form-Felder füllen
    form.name.value = data.name || '';
    form.email.value = data.email || '';
    form.message.value = data.message || '';

    console.log('Form-Daten wiederhergestellt');
  }
}

// Form-Daten speichern
function saveFormData() {
  const data = {
    name: form.name.value,
    email: form.email.value,
    message: form.message.value,
    savedAt: new Date().toISOString()
  };

  localStorage.setItem(STORAGE_KEY, JSON.stringify(data));
}

// Auto-Save bei Änderungen
form.addEventListener('input', () => {
  saveFormData();
  console.log('Form gespeichert');
});

// Nach erfolgreichem Submit löschen
form.addEventListener('submit', (e) => {
  e.preventDefault();

  // ... Form senden ...

  // Draft löschen
  localStorage.removeItem(STORAGE_KEY);
  console.log('Form gesendet, Draft gelöscht');
});

// Beim Laden wiederherstellen
loadFormData();

Beispiel 3: Shopping Cart

Einkaufswagen mit LocalStorage
const cart = {
  // Cart laden
  load() {
    const saved = localStorage.getItem('cart');
    return saved ? JSON.parse(saved) : [];
  },

  // Cart speichern
  save(items) {
    localStorage.setItem('cart', JSON.stringify(items));
  },

  // Produkt hinzufügen
  addItem(product) {
    const items = this.load();

    // Prüfen ob schon vorhanden
    const existingIndex = items.findIndex(item => item.id === product.id);

    if (existingIndex >= 0) {
      // Menge erhöhen
      items[existingIndex].quantity++;
    } else {
      // Neu hinzufügen
      items.push({ ...product, quantity: 1 });
    }

    this.save(items);
    this.updateUI();
  },

  // Produkt entfernen
  removeItem(productId) {
    let items = this.load();
    items = items.filter(item => item.id !== productId);
    this.save(items);
    this.updateUI();
  },

  // Menge ändern
  updateQuantity(productId, quantity) {
    const items = this.load();
    const item = items.find(i => i.id === productId);

    if (item) {
      if (quantity <= 0) {
        this.removeItem(productId);
      } else {
        item.quantity = quantity;
        this.save(items);
        this.updateUI();
      }
    }
  },

  // Gesamtpreis berechnen
  getTotal() {
    const items = this.load();
    return items.reduce((sum, item) => {
      return sum + (item.price * item.quantity);
    }, 0);
  },

  // UI aktualisieren
  updateUI() {
    const items = this.load();
    const count = items.reduce((sum, item) => sum + item.quantity, 0);

    // Badge aktualisieren
    document.getElementById('cart-count').textContent = count;

    // Gesamt aktualisieren
    document.getElementById('cart-total').textContent = `${this.getTotal().toFixed(2)}€`;
  }
};

// Verwenden
cart.addItem({ id: 1, name: 'Laptop', price: 999.99 });
cart.addItem({ id: 2, name: 'Mouse', price: 29.99 });
cart.updateQuantity(1, 2); // 2x Laptop

console.log('Gesamt:', cart.getTotal()); // 2029.97
console.log('Items:', cart.load());

Beispiel 4: Letzte Suchanfragen speichern

Search History
const searchHistory = {
  MAX_ITEMS: 10,
  STORAGE_KEY: 'search_history',

  // History laden
  load() {
    const saved = localStorage.getItem(this.STORAGE_KEY);
    return saved ? JSON.parse(saved) : [];
  },

  // Suche hinzufügen
  add(query) {
    if (!query || query.trim() === '') return;

    let history = this.load();

    // Duplikate entfernen
    history = history.filter(item => item !== query);

    // Vorne hinzufügen
    history.unshift(query);

    // Auf MAX_ITEMS begrenzen
    if (history.length > this.MAX_ITEMS) {
      history = history.slice(0, this.MAX_ITEMS);
    }

    localStorage.setItem(this.STORAGE_KEY, JSON.stringify(history));
  },

  // Einzelnen Eintrag löschen
  remove(query) {
    let history = this.load();
    history = history.filter(item => item !== query);
    localStorage.setItem(this.STORAGE_KEY, JSON.stringify(history));
  },

  // Alles löschen
  clear() {
    localStorage.removeItem(this.STORAGE_KEY);
  },

  // Als HTML-Liste ausgeben
  renderList() {
    const history = this.load();

    if (history.length === 0) {
      return '<p>Keine letzten Suchen</p>';
    }

    return history.map(query => `
      <li>
        <button onclick="search('${query}')">${query}</button>
        <button onclick="searchHistory.remove('${query}')">×</button>
      </li>
    `).join('');
  }
};

// Suche ausführen
function search(query) {
  searchHistory.add(query);
  console.log(`Suche nach: ${query}`);
  // ... Suche durchführen ...
}

// Event Listener
document.getElementById('search-form').addEventListener('submit', (e) => {
  e.preventDefault();
  const query = e.target.query.value;
  search(query);
});

SessionStorage - Temporäre Daten

SessionStorage funktioniert genau wie LocalStorage, aber Daten sind nur für die aktuelle Session.

SessionStorage Beispiel
// Temporäre Daten speichern
sessionStorage.setItem('tempToken', 'abc123');
sessionStorage.setItem('currentStep', '3');

// Auslesen
const token = sessionStorage.getItem('tempToken');
const step = sessionStorage.getItem('currentStep');

// Löschen
sessionStorage.removeItem('tempToken');

// Alles löschen
sessionStorage.clear();

// Use Case: Multi-Step Form
const formWizard = {
  saveStep(stepNumber, data) {
    sessionStorage.setItem(`step_${stepNumber}`, JSON.stringify(data));
  },

  getStep(stepNumber) {
    const saved = sessionStorage.getItem(`step_${stepNumber}`);
    return saved ? JSON.parse(saved) : null;
  },

  clearAll() {
    sessionStorage.clear();
  }
};

// Schritt 1 speichern
formWizard.saveStep(1, {
  name: 'Anna',
  email: 'anna@example.com'
});

// Schritt 1 laden
const step1Data = formWizard.getStep(1);

Storage Events - Änderungen beobachten

Mit dem storage Event kannst du Änderungen in anderen Tabs mitbekommen!

Storage Events nutzen
// Storage Event Listener
window.addEventListener('storage', (e) => {
  console.log('Storage wurde geändert!');
  console.log('Key:', e.key);
  console.log('Alter Wert:', e.oldValue);
  console.log('Neuer Wert:', e.newValue);
  console.log('URL:', e.url);

  // Beispiel: Theme sync zwischen Tabs
  if (e.key === 'theme') {
    document.body.classList.toggle('dark-mode', e.newValue === 'dark');
  }
});

// WICHTIG: Event wird NUR in ANDEREN Tabs ausgelöst!
// Nicht im gleichen Tab wo die Änderung passiert

// Use Case: User logout in allen Tabs
window.addEventListener('storage', (e) => {
  if (e.key === 'isLoggedIn' && e.newValue === 'false') {
    // User wurde in anderem Tab ausgeloggt
    window.location.href = '/login';
  }
});

Storage Limits & Error Handling

Quota Exceeded Error behandeln
function safeSetItem(key, value) {
  try {
    localStorage.setItem(key, value);
    return true;
  } catch (error) {
    if (error.name === 'QuotaExceededError') {
      console.error('Storage ist voll!');

      // Alte Daten löschen
      const keys = Object.keys(localStorage);

      // Älteste Einträge löschen
      if (keys.length > 0) {
        localStorage.removeItem(keys[0]);

        // Nochmal versuchen
        try {
          localStorage.setItem(key, value);
          return true;
        } catch (e) {
          console.error('Storage immer noch voll');
        }
      }
    }

    console.error('Storage Error:', error);
    return false;
  }
}

// Verwenden
if (safeSetItem('data', 'value')) {
  console.log('Gespeichert');
} else {
  console.log('Fehler beim Speichern');
}

Storage Größe prüfen

Verwendeten Speicher berechnen
function getStorageSize() {
  let total = 0;

  for (let key in localStorage) {
    if (localStorage.hasOwnProperty(key)) {
      total += localStorage[key].length + key.length;
    }
  }

  return {
    bytes: total,
    kb: (total / 1024).toFixed(2),
    mb: (total / 1024 / 1024).toFixed(2)
  };
}

const size = getStorageSize();
console.log(`Storage: ${size.kb} KB verwendet`);

// Alle Einträge mit Größe
function listStorageItems() {
  const items = [];

  for (let key in localStorage) {
    if (localStorage.hasOwnProperty(key)) {
      const value = localStorage[key];
      const size = (value.length + key.length) / 1024;

      items.push({
        key,
        size: size.toFixed(2) + ' KB',
        value: value.substring(0, 50) + '...'
      });
    }
  }

  return items.sort((a, b) => parseFloat(b.size) - parseFloat(a.size));
}

console.table(listStorageItems());

📝 Quiz

Wann werden SessionStorage Daten gelöscht?

Tipps & Tricks

Expire-Funktion für LocalStorage

const storageWithExpiry = {
  set(key, value, expiryInMinutes) {
    const now = new Date();
    const item = {
      value: value,
      expiry: now.getTime() + (expiryInMinutes * 60 * 1000)
    };
    localStorage.setItem(key, JSON.stringify(item));
  },

  get(key) {
    const itemStr = localStorage.getItem(key);

    if (!itemStr) return null;

    const item = JSON.parse(itemStr);
    const now = new Date();

    // Abgelaufen?
    if (now.getTime() > item.expiry) {
      localStorage.removeItem(key);
      return null;
    }

    return item.value;
  }
};

// Verwenden
storageWithExpiry.set('token', 'abc123', 30); // 30 Minuten
const token = storageWithExpiry.get('token');

Storage als Observer Pattern

const observableStorage = {
  listeners: {},

  setItem(key, value) {
    localStorage.setItem(key, value);

    // Alle Listener benachrichtigen
    if (this.listeners[key]) {
      this.listeners[key].forEach(callback => {
        callback(value);
      });
    }
  },

  on(key, callback) {
    if (!this.listeners[key]) {
      this.listeners[key] = [];
    }
    this.listeners[key].push(callback);
  }
};

// Verwenden
observableStorage.on('theme', (newTheme) => {
  console.log('Theme changed:', newTheme);
  document.body.className = newTheme;
});

observableStorage.setItem('theme', 'dark');

Komprimierung für große Daten

// Vereinfachte Komprimierung mit LZ-String (externe Library)
function compressAndStore(key, data) {
  const compressed = LZString.compress(JSON.stringify(data));
  localStorage.setItem(key, compressed);
}

function decompressAndLoad(key) {
  const compressed = localStorage.getItem(key);
  if (!compressed) return null;

  const decompressed = LZString.decompress(compressed);
  return JSON.parse(decompressed);
}

Häufige Fehler

Fehler 1: Objekte direkt speichern

FALSCH:

const user = { name: 'Anna', age: 25 };
localStorage.setItem('user', user);
console.log(localStorage.getItem('user')); // '[object Object]' ❌

RICHTIG:

const user = { name: 'Anna', age: 25 };
localStorage.setItem('user', JSON.stringify(user));
const saved = JSON.parse(localStorage.getItem('user'));

Fehler 2: Keine Error Handling

FALSCH:

const data = JSON.parse(localStorage.getItem('user'));
// Kann crashen wenn nicht valid JSON!

RICHTIG:

try {
  const data = JSON.parse(localStorage.getItem('user'));
} catch (error) {
  console.error('Parse error:', error);
  const data = null;
}

Fehler 3: Sensible Daten speichern

FALSCH:

// NIEMALS Passwörter, Tokens, etc. im LocalStorage!
localStorage.setItem('password', 'secret123'); // ❌ UNSICHER!
localStorage.setItem('creditCard', '1234-5678-9012-3456'); // ❌ GEFÄHRLICH!

RICHTIG:

// Nur unkritische Daten
localStorage.setItem('theme', 'dark'); // ✅
localStorage.setItem('language', 'de'); // ✅
localStorage.setItem('preferences', JSON.stringify({ volume: 50 })); // ✅

Fehler 4: Storage Events im gleichen Tab erwarten

FALSCH:

localStorage.setItem('key', 'value');
// Storage Event wird NICHT im gleichen Tab gefeuert!

RICHTIG:

// Storage Events kommen nur von ANDEREN Tabs
// Für gleichen Tab: Custom Event oder Observer Pattern nutzen
🎯

Zusammenfassung

Du hast gelernt:

  • ✅ LocalStorage - Dauerhafte Browser-Speicherung
  • ✅ SessionStorage - Temporäre Session-Daten
  • setItem(), getItem(), removeItem(), clear()
  • ✅ JSON für Objekte speichern
  • ✅ Storage Events für Tab-Synchronisation
  • ✅ Error Handling & Quota Management
  • ✅ Praktische Use Cases (Theme, Cart, Forms)

Key Takeaways:

  • LocalStorage = dauerhaft, SessionStorage = nur Session
  • Nur Strings speichern → JSON.stringify/parse für Objekte
  • Limit: ~5-10 MB pro Domain
  • Storage Events nur in anderen Tabs
  • KEINE sensiblen Daten (Passwörter, Tokens)!
  • Immer Error Handling verwenden

Best Practices:

  • Helper-Funktionen für JSON Handling
  • Try/Catch für Parse Errors
  • Expire-Logik für temporäre Daten
  • Storage Size monitoring
  • Nur unkritische Daten speichern

Praktische Übungen

Übung 1: Theme Switcher

Erstelle einen Dark/Light Mode Toggle der:

  1. Theme beim Laden lädt
  2. Theme beim Click wechselt
  3. Theme in LocalStorage speichert

Übung 2: Todo-Liste

Baue eine Todo-Liste die:

  1. Todos in LocalStorage speichert
  2. Beim Laden wiederherstellt
  3. Beim Löschen aktualisiert

Übung 3: Form Auto-Save

Erstelle ein Formular das:

  1. Alle 2 Sekunden speichert
  2. Beim Laden wiederherstellt
  3. Nach Submit löscht

Übung 4: Shopping Cart

Implementiere einen Warenkorb mit:

  1. Produkte hinzufügen
  2. Menge ändern
  3. Gesamtpreis berechnen
  4. In LocalStorage persistent

Übung 5: Search History

Baue eine Suchhistorie die:

  1. Letzte 10 Suchen speichert
  2. Duplikate entfernt
  3. Einzelne Einträge löschbar macht
  4. Als Dropdown anzeigt
JavaScriptLektion 16 von 17
94% abgeschlossen
Lektion abgeschlossen!

Gut gemacht! 🎉

Du hast "JavaScript Storage API - LocalStorage & SessionStorage" abgeschlossen

Artikel bewerten

0.0 (0 Bewertungen)

Bitte einloggen um zu bewerten