LocalStorage, sessionStorage

Objekty webového úložiště localStorage a sessionStorage umožňují uložit páry klíč/hodnota v prohlížeči.

Zajímavé na nich je, že data přežijí obnovení stránky (pro sessionStorage ) a dokonce i úplný restart prohlížeče (pro localStorage ). To uvidíme velmi brzy.

Už máme sušenky. Proč další objekty?

  • Na rozdíl od souborů cookie se objekty webového úložiště neodesílají na server s každým požadavkem. Díky tomu můžeme uložit mnohem více. Většina moderních prohlížečů umožňuje alespoň 5 megabajtů dat (nebo více) a má nastavení pro jeho konfiguraci.
  • Na rozdíl od souborů cookie také server nemůže manipulovat s objekty úložiště prostřednictvím záhlaví HTTP. Vše se děje v JavaScriptu.
  • Úložiště je vázáno na zdroj (triplet doména/protokol/port). To znamená, že různé protokoly nebo subdomény vyvozují různé objekty úložiště, nemohou navzájem přistupovat k datům.

Oba objekty úložiště poskytují stejné metody a vlastnosti:

  • setItem(key, value) – uložit pár klíč/hodnota.
  • getItem(key) – získat hodnotu pomocí klíče.
  • removeItem(key) – odeberte klíč s jeho hodnotou.
  • clear() – smazat vše.
  • key(index) – získat klíč na dané pozici.
  • length – počet uložených položek.

Jak můžete vidět, je to jako Map kolekce (setItem/getItem/removeItem ), ale také umožňuje přístup pomocí indexu s key(index) .

Podívejme se, jak to funguje.

ukázka místního úložiště

Hlavní rysy localStorage jsou:

  • Sdíleno mezi všemi kartami a okny ze stejného zdroje.
  • Platnost dat nevyprší. Zůstane po restartu prohlížeče a dokonce i restartu OS.

Pokud například spustíte tento kód…

localStorage.setItem('test', 1);

…A zavřete/otevřete prohlížeč nebo prostě otevřete stejnou stránku v jiném okně, pak to můžete získat takto:

alert( localStorage.getItem('test') ); // 1

Musíme být pouze na stejném původu (doména/port/protokol), cesta url se může lišit.

localStorage je sdílen mezi všemi okny se stejným původem, takže pokud nastavíme data v jednom okně, změna se projeví v jiném.

Objektový přístup

Můžeme také použít jednoduchý objektový způsob získávání/nastavení klíčů, jako je tento:

// set key
localStorage.test = 2;

// get key
alert( localStorage.test ); // 2

// remove key
delete localStorage.test;

To je z historických důvodů povoleno a většinou to funguje, ale obecně se to nedoporučuje, protože:

  1. Pokud je klíč vygenerován uživatelem, může to být cokoliv, například length nebo toString nebo jinou vestavěnou metodou localStorage . V tom případě getItem/setItem funguje dobře, zatímco objektový přístup selže:

    let key = 'length';
    localStorage[key] = 5; // Error, can't assign length
  2. Je tam storage událost se spustí, když upravíme data. K této události nedochází u objektového přístupu. To uvidíme později v této kapitole.

Procházení kláves

Jak jsme viděli, metody poskytují funkci „získat/nastavit/odebrat pomocí klíče“. Jak ale získat všechny uložené hodnoty nebo klíče?

Objekty úložiště bohužel nelze iterovat.

Jedním ze způsobů je smyčka přes ně jako přes pole:

for(let i=0; i<localStorage.length; i++) {
  let key = localStorage.key(i);
  alert(`${key}: ${localStorage.getItem(key)}`);
}

Dalším způsobem je použití for key in localStorage smyčky, stejně jako to děláme s běžnými objekty.

Iteruje přes klíče, ale také vydává několik vestavěných polí, která nepotřebujeme:

// bad try
for(let key in localStorage) {
  alert(key); // shows getItem, setItem and other built-in stuff
}

…Potřebujeme tedy buď filtrovat pole z prototypu pomocí hasOwnProperty zkontrolujte:

for(let key in localStorage) {
  if (!localStorage.hasOwnProperty(key)) {
    continue; // skip keys like "setItem", "getItem" etc
  }
  alert(`${key}: ${localStorage.getItem(key)}`);
}

…Nebo stačí získat „vlastní“ klíče s Object.keys a v případě potřeby přes ně smyčku:

let keys = Object.keys(localStorage);
for(let key of keys) {
  alert(`${key}: ${localStorage.getItem(key)}`);
}

To druhé funguje, protože Object.keys vrací pouze klíče, které patří k objektu, ignoruje prototyp.

Pouze řetězce

Pamatujte, že klíč i hodnota musí být řetězce.

Pokud by šlo o jakýkoli jiný typ, například číslo nebo objekt, převede se na řetězec automaticky:

localStorage.user = {name: "John"};
alert(localStorage.user); // [object Object]

Můžeme použít JSON pro ukládání objektů:

localStorage.user = JSON.stringify({name: "John"});

// sometime later
let user = JSON.parse( localStorage.user );
alert( user.name ); // John

Také je možné stringovat celý objekt úložiště, např. pro účely ladění:

// added formatting options to JSON.stringify to make the object look nicer
alert( JSON.stringify(localStorage, null, 2) );

sessionStorage

sessionStorage objekt se používá mnohem méně často než localStorage .

Vlastnosti a metody jsou stejné, ale jsou mnohem omezenější:

  • sessionStorage existuje pouze na aktuální kartě prohlížeče.
    • Jiná karta se stejnou stránkou bude mít jiné úložiště.
    • Je však sdílen mezi prvky iframe na stejné kartě (za předpokladu, že pocházejí ze stejného původu).
  • Data vydrží obnovení stránky, ale nezavření/otevření karty.

Podívejme se na to v praxi.

Spusťte tento kód…

sessionStorage.setItem('test', 1);

…Pak obnovte stránku. Nyní můžete stále získat data:

alert( sessionStorage.getItem('test') ); // after refresh: 1

…Pokud ale stejnou stránku otevřete na jiné kartě a zkusíte to tam znovu, výše uvedený kód vrátí null , což znamená „nic nebylo nalezeno“.

To je přesně proto, že sessionStorage je vázán nejen na původ, ale také na kartu prohlížeče. Z tohoto důvodu sessionStorage se používá střídmě.

Událost úložiště

Když se data aktualizují v localStorage nebo sessionStorage , spouštěče událostí úložiště, s vlastnostmi:

  • key – klíč, který byl změněn (null pokud .clear() se nazývá).
  • oldValue – stará hodnota (null pokud je klíč nově přidán).
  • newValue – nová hodnota (null pokud je klíč odstraněn).
  • url – adresa URL dokumentu, kde došlo k aktualizaci.
  • storageArea – buď localStorage nebo sessionStorage objekt, kde k aktualizaci došlo.

Důležité je:událost se spustí na všech window objekty, kde je úložiště přístupné, kromě toho, který to způsobil.

Pojďme to upřesnit.

Představte si, že máte dvě okna se stejným webem v každém. Takže localStorage je sdílena mezi nimi.

Možná budete chtít otevřít tuto stránku ve dvou oknech prohlížeče a otestovat níže uvedený kód.

Pokud obě okna naslouchají window.onstorage , pak každý z nich bude reagovat na aktualizace, ke kterým došlo v druhém.

// triggers on updates made to the same storage from other documents
window.onstorage = event => { // can also use window.addEventListener('storage', event => {
  if (event.key != 'now') return;
  alert(event.key + ':' + event.newValue + " at " + event.url);
};

localStorage.setItem('now', Date.now());

Upozorňujeme, že událost také obsahuje:event.url – adresa URL dokumentu, kde byla data aktualizována.

Také event.storageArea obsahuje objekt úložiště – událost je stejná pro oba sessionStorage a localStorage , takže event.storageArea odkazuje na ten, který byl upraven. Můžeme v něm dokonce chtít něco nastavit, abychom „reagovali“ na změnu.

To umožňuje různým oknům ze stejného zdroje vyměňovat si zprávy.

Moderní prohlížeče také podporují Broadcast channel API, speciální API pro komunikaci mezi okny stejného původu, je plnohodnotnější, ale méně podporované. Existují knihovny, které toto API polyfillují na základě localStorage , díky kterým je dostupná všude.

Shrnutí

Objekty webového úložiště localStorage a sessionStorage umožňují uložit klíč/hodnotu v prohlížeči.

  • Oba key a value musí být řetězce.
  • Limit je 5 MB+, záleží na prohlížeči.
  • Jejich platnost nevyprší.
  • Data jsou vázána na zdroj (doména/port/protokol).
localStorage sessionStorage
Sdíleno mezi všemi kartami a okny se stejným původem Viditelné na kartě prohlížeče, včetně prvků iframe ze stejného původu
Přežije restart prohlížeče Přetrvává obnovení stránky (ale ne zavření karty)

API:

  • setItem(key, value) – uložit pár klíč/hodnota.
  • getItem(key) – získat hodnotu pomocí klíče.
  • removeItem(key) – odeberte klíč s jeho hodnotou.
  • clear() – smazat vše.
  • key(index) – získat číslo klíče index .
  • length – počet uložených položek.
  • Použijte Object.keys získat všechny klíče.
  • Ke klíčům přistupujeme jako k vlastnostem objektu, v tomto případě storage událost není spuštěna.

Událost úložiště:

  • Spouští na setItem , removeItem , clear hovory.
  • Obsahuje všechna data o operaci (key/oldValue/newValue ), dokument url a objekt úložiště storageArea .
  • Spouštěče na všech window objekty, které mají přístup k úložišti kromě toho, který jej vygeneroval (na kartě pro sessionStorage , globálně pro localStorage ).