Samenvatting
DOM Storage is de naam van een set opslag-gerelateerde features voor het eerst geïntroduceerd in de Web Applications 1.0-specificatie en nu afgesplitst in zijn eigen W3C Web Storage-specificatie. DOM Storage is ontworpen met als doel een grotere, beter beveiligde en makkelijker te gebruiken alternatief voor opslaan van informatie dan cookies te zijn. Het is geintroduceerd met Firefox 2 en Safari 4.
Omschrijving
Het DOM Storage-mechanisme is een manier om key/value-paren op een veilige manier op te slaan en later ophalen voor gebruik. Het doel van deze toevoeging is om een uitgebreide manier te leveren waardoor het mogelijk wordt om interactieve applicaties te maken (inclusief geavanceerde capaciteiten, zoals het 'offline' kunnen werken voor langere tijd).
Op Mozilla-gebaseerde browsers, Internet Explorer 8+, Safari 4+, Chrome en Opera leveren allemaal een werkende implementatie van de DOM Storage-specificatie. (In het geval dat je ook oudere versies van IE ondersteunt, kan het handig zijn om te weten dat er een legacy feature genaamd "userData behavior" in pre-8 versies van IE zit)
DOM Storage is handig omdat er geen goede browser-only methode bestaat voor het aanhoudend opslaan van redelijke hoeveelheden data voor een willekeurige tijdsperiode. Browsercookies hebben gelimiteerde capaciteit en geven geen mogelijkheid voor het organiseren van aanhoudende data. Andere methodes (zoals Flash Local Storage) vereisen een externe plugin.
Een van de eerste publieke applicaties die gebruik maakt van de nieuwe DOM Storage-functionalitiet (naast Internet Explorer's userData Behavior) was halfnote (een notitieapplicatie) geschreven door Aaron Boodman. In zijn applicatie, sloeg Aaron notities zowel op door middel van een server (als een internetverbinding beschikbaar was) en een lokale dataopslag. Dit maakte het voor de gebruiker mogelijk om veilig opgeslagen notities te maken met een sporadische internetverbinding.
Ondanks dat het concept, en implementatie, in halfnote redelijk simpel was, laat de creatie zien wat de mogelijkheden zijn voor een nieuw soort webapplicaties die zowel online als offline bruikbaar zijn.
Referentie
Het hierop volgende zijn globale objecten die bestaan als een property van elk window
object. Dit betekent dat ze aangesproken kunnen worden als sessionStorage
of window.sessionStorage
. (Dit is belangrijk omdat je hierdoor ze kan gebruiken in IFrames om extra data op te slaan, aan te spreken, buiten wat er direct beschikbaar is in je eigen pagina.)
Storage
Dit is een constructor (Storage
) voor alle Storage instanties (sessionStorage
en globalStorage[location.hostname]).
Het zetten van Storage.prototype.removeKey = function(key){ this.removeItem(this.key(key)) }
zou zowel localStorage.removeKey en sessionStorage.removeKey
als zodanig veranderen.
globalStorage
items zijn geen instanties van Storage
, maar zijn instanties van StorageObsolete
.
Storage
is gedefineerd door de WhatWG Storage Interface als het volgende:
interface Storage { readonly attribute unsigned long length; [IndexGetter] DOMString key(in unsigned long index); [NameGetter] DOMString getItem(in DOMString key); [NameSetter] void setItem(in DOMString key, in DOMString data); [NameDeleter] void removeItem(in DOMString key); void clear(); };
.toString
methode voordat het wordt opgeslagen. Een gewoon object opslaan resulteert dus in een string "[object Object]"
dat wordt opgeslagen, in plaats van het object of zijn JSON-representatie. Het gebruik van native JSON parsing en serializatie methodes geleverd door de browser is een goede en veelvuldig gebruikte manier om objecten in string formaat op te slaan.sessionStorage
Dit is een globaal object (sessionStorage
) dat een opslagruimte biedt gedurende de duur van paginasessie. Een paginasessie duurt zolang de browser open is en overleeft het herladen van de pagina en paginarestoraties. Het openen van een pagina in een nieuwe tab of window zorgt ervoor dat een nieuwe sessie wordt gestart.
// Sla data op in de huidige sessie store sessionStorage.setItem("username", "John"); // Spreek de opgeslagen data aan alert( "username = " + sessionStorage.getItem("username"));
Het sessionStorage
object is het handigst voor het bijhouden van tijdelijke data die behouden moet blijven als de pagina per ongeluk wordt herladen.
Voor Firefox 3.5, werd sessionStorage data niet automatisch hersteld van een browsercrash. Startend vanaf Firefox 3.5, werkt dit zoals per de specificatie.
Voorbeelden:
Automatisch opslaan van de inhoud van een tekstveld en als de browser per ongeluk herladen wordt, het herstellen van de inhoud van het tekstveld, zodat geen tekst verloren gaat.
// Haal het tekstveld op dat we gaan volgen var field = document.getElementById("field"); // Kijk of er een autosave waarde is // (Dit gebeurt alleen als de pagina per ongeluk wordt herladen) if ( sessionStorage.getItem("autosave")) { // Herstel de inhoud van het tekstveld field.value = sessionStorage.getItem("autosave"); } // Bekijk de inhoud van het tekstveld iedere seconde setInterval(function(){ // En sla het resultaat op in het sessie storage object sessionStorage.setItem("autosave", field.value); }, 1000);
Meer informatie:
localStorage
localStorage
is hetzelfde als sessionStorage
met dezelfde same-origin regels toegepast, maar is vasthoudend. localStorage
werd geintroduceerd in Firefox 3.5.
Compatibility
Storage
objecten zijn een recente toevoeging aan de standaard. Hierdoor is het mogelijk dat ze niet aanwezig zijn in alle browsers. Je kan hier omheen werken door het toevoegen van en van de volgende twee stukken code aan het begin van je scripts. Dit maakt het gebruik van het localStorage
object mogelijk in implementaties die het niet native ondersteunen.
Dit algoritme is een exacte imitatie van het localStorage
object, maar maakt gebruik van cookies.
if (!window.localStorage) { Object.defineProperty(window, "localStorage", new (function () { var aKeys = [], oStorage = {}; Object.defineProperty(oStorage, "getItem", { value: function (sKey) { return sKey ? this[sKey] : null; }, writable: false, configurable: false, enumerable: false }); Object.defineProperty(oStorage, "key", { value: function (nKeyId) { return aKeys[nKeyId]; }, writable: false, configurable: false, enumerable: false }); Object.defineProperty(oStorage, "setItem", { value: function (sKey, sValue) { if(!sKey) { return; } document.cookie = escape(sKey) + "=" + escape(sValue) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/"; }, writable: false, configurable: false, enumerable: false }); Object.defineProperty(oStorage, "length", { get: function () { return aKeys.length; }, configurable: false, enumerable: false }); Object.defineProperty(oStorage, "removeItem", { value: function (sKey) { if(!sKey) { return; } document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/"; }, writable: false, configurable: false, enumerable: false }); this.get = function () { var iThisIndx; for (var sKey in oStorage) { iThisIndx = aKeys.indexOf(sKey); if (iThisIndx === -1) { oStorage.setItem(sKey, oStorage[sKey]); } else { aKeys.splice(iThisIndx, 1); } delete oStorage[sKey]; } for (aKeys; aKeys.length > 0; aKeys.splice(0, 1)) { oStorage.removeItem(aKeys[0]); } for (var aCouple, iKey, nIdx = 0, aCouples = document.cookie.split(/\s*;\s*/); nIdx < aCouples.length; nIdx++) { aCouple = aCouples[nIdx].split(/\s*=\s*/); if (aCouple.length > 1) { oStorage[iKey = unescape(aCouple[0])] = unescape(aCouple[1]); aKeys.push(iKey); } } return oStorage; }; this.configurable = false; this.enumerable = true; })()); }
localStorage.setItem()
en localStorage.removeItem()
om een key toe te voegen, te veranderen of te verwijderen. Het gebruik van de methodes localStorage.yourKey = yourValue;
en delete localStorage.yourKey;
om een key te zetten en te verwijderen is niet een veilige manier met deze code. Je kan ook de naam veranderen en het alleen gebruiken om een documents cookies te beheren onafhankelijk van het localStorage object. Door het aanpassen van de string "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/"
naar: "; path=/"
(en het aanpassen van de naam) wordt dit een sessionStorage
polyfill in plaat van een localStorage
polyfill.Hier is nog een, minder precieze, imitatie van het localStorage
object. Het is simpeler dan de vorige, maar is compatible met oudere browsers, zoals pre-8 versie van IE (werkend getest tot Internet Explorer 6). Het maakt ook gebruik van cookies.
if (!window.localStorage) { window.localStorage = { getItem: function (sKey) { if (!sKey || !this.hasOwnProperty(sKey)) { return null; } return unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"), "$1")); }, key: function (nKeyId) { return unescape(document.cookie.replace(/\s*\=(?:.(?!;))*$/, "").split(/\s*\=(?:[^;](?!;))*[^;]?;\s*/)[nKeyId]); }, setItem: function (sKey, sValue) { if(!sKey) { return; } document.cookie = escape(sKey) + "=" + escape(sValue) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/"; this.length = document.cookie.match(/\=/g).length; }, length: 0, removeItem: function (sKey) { if (!sKey || !this.hasOwnProperty(sKey)) { return; } document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/"; this.length--; }, hasOwnProperty: function (sKey) { return (new RegExp("(?:^|;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie); } }; window.localStorage.length = (document.cookie.match(/\=/g) || window.localStorage).length; }
localStorage.getItem()
, localStorage.setItem()
and localStorage.removeItem()
om een key te krijgen, veranderen of verwijderen. Het gebruik van de methode localStorage.yourKey
om een key te krijgen veranderen of verwijderen is niet toegestaan bij deze code. Je kan ook de naam veranderen en het alleen gebruiken om een documents cookies te beheren onafhankelijk van het localStorage object. Door het aanpassen van de string "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/"
into: "; path=/"
(en het aanpassen van de naam) wordt dit een sessionStorage
polyfill in plaat van een localStorage
polyfill.Compatibility en de relatie met globalStorage
localStorage
is hetzelfde als globalStorage[location.hostname]
, met de uitzondering dat deze gescoped is naar een HTML5 origin (scheme + hostname + non-standard port) en dat localStorage
een instantie is van Storage
in tegenstelling tot globalStorage[location.hostname]
wat een instantie is van StorageObsolete
welke hieronder wordt behandeld. Bijvoorbeeld, https://example.com is niet bereikbaar voor het localStorage
object als https://example.com maar ze kunnen hetzelfde globalStorage
item aanspreken. localStorage
is een standaard interface terwijl globalStorage
een non-standaard is, dus dien je niet er van uit te gaan dat deze beschikbaar is.
Merk op dat het zetten van een property op globalStorage[location.hostname]
deze niet zet op localStorage
en dat het uitbreiden van Storage.prototype
geen effect heeft op globalStorage
items, alleen het uitbreiden van StorageObsolete.prototype
werkt.
globalStorage
Obsolete since Gecko 13.0 (Firefox 13.0 / Thunderbird 13.0 / SeaMonkey 2.10)
This feature is obsolete. Although it may still work in some browsers, its use is discouraged since it could be removed at any time. Try to avoid using it.
globalStorage
is verouderd sinds Gecko 1.9.1 (Firefox 3.5) en niet meer ondersteund sinds Gecko 13 (Firefox 13). Gebruik localStorage
ter vervanging. Deze voorgestelde specificatie is verwijderd van de HTML5 specificatie ten gunste van localStorage
, wat geimplementeerd is in Firefox 3.5. Dit is een globaal object (globalStorage
) dat meerdere prive opslag ruimtes bijhoud die gebruikt kunnen worden om data over een langere periode op te slaan (bijv. gedurende meerdere pagina en browser sessies).
globalStorage
is niet een Storage
instantie, maar een StorageList
instantie dat StorageObsolete
instanties bevat.// Sla data op dat alleen scripts op het mozilla.org domein kunnen aanspreken globalStorage['mozilla.org'].setItem("snippet", "<b>Hello</b>, how are you?");
Specifiek, levert het globalStorage
object toegang tot een aantal verschillende opslag objecten waar data in kan worden opgeslagen. Bijvoorbeeld, als we een web pagina maakten dat globalStorage
gebruikte op dit domein (developer.mozilla.org) dan hadden we de volgende opslag object tot onze beschikking:
globalStorage['developer.mozilla.org']
- Alle web paginas in een developer.mozilla.org sub-domein kan zowel lezen als schrijven in dit opslag object.
Voorbeelden:
Elk van deze voorbeelden vereist dat je een script stopt (met de volgende code) in elke pagina waar je het resultaat wilt zien.
Onthoud een gebruikers gebruikersnaam voor het specifieke sub-domein dat wordt bezocht:
globalStorage['developer.mozilla.org'].setItem("username", "John");
Houd bij hoe vaak een gebruiker een pagina bezoekt op je domein:
// parseInt moet gebruikt worden omdat alle dat als string wordt opgeslagen globalStorage['mozilla.org'].setItem("visits", parseInt(globalStorage['mozilla.org'].getItem("visits") || 0 ) + 1);
Opslag locatie en weggooien van de data
In Firefox de DOM storage data wordt opgeslagen in het webappsstore.sqlite bestand in de profiel folder (er is ook een chromeappsstore.sqlite bestand dat gebruikt wordt om de browsers eigen data op te slaan, met name voor de start pagina - about:home, maar mogelijk ook voor andere interne pagina met "about:" URLs).
- DOM Storage kan verwijderd worden via "Tools -> Clear Recent History -> Cookies" als de tijd bereik "Everyting" is (via nsICookieManager::removeAll)
- Maar niet wanneer een andere tijd bereik is gespecificeerd: (bug 527667)
- Verschijnt niet in Tools -> Options -> Privacy -> Remove individual cookies (bug 506692)
- DOM Storage wordt niet verwijderd via Tools -> Options -> Advanced -> Network -> Offline data -> Clear Now.
- Verschijnt niet in de "Tools -> Options -> Advanced -> Network -> Offline data" lijst, tenzij de site ook de offline cache gebruikt. Als de site wel verschijnt in de lijst, dan wordt de DOM storage data verwijderd samen met de offline cache als er op de Verwijder knop wordt gedrukt.
Zie ook clearing offline resources cache.
Meer informatie
- Web Storage (W3C Web Apps Working Group)
- Enable/Disable DOM Storage in Firefox or SeaMonkey
Voorbeelden
- JavaScript Web Storage Tutorial: Creating an Address Book Application - hands-on tutorial die beschrijft hoe de Web Storage API te gebruiken door een simpele adresboek applicatie te maken
- offline web applications at hacks.mozilla.org - laat een offline app demo zien en legt uit hoe het werkt.
- Noteboard - Notitie applicatie dat alle data lokaal opslaat.
- jData - Een gedeelde localStorage object interface dat door elke website kan worden aangesproken en werkt in Firefox 3+, Webkit 3.1.2+ nightlies, en IE8. Zie het als een pseudo-globalStorage[""] maar met schrijf toegang beschermd door gebruikers bevestiging.
- HTML5 localStorage example. Simpel en eenvoudig te begrijpen voorbeeld van localStorage. Slaat- en haalt teksten op en toont een lijst van opgeslagen items. Getest in Firefox 3 en hoger.
- HTML5 Session Storage. Een zeer simpel voorbeeld van sessionStorage. Bevat ook een voorbeeld van localStorage. Getest in Firefox 3.6 of hoger.
Basic DOMStorage Examples- Broken in Firefox 3 and up due to use of globalStorage on one domain level up from the current domain which is not allowed in Firefox 3.halfnote- (displaying broken in Firefox 3) Note writing application that uses DOM Storage.
Browser compatibility
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari (WebKit) |
---|---|---|---|---|---|
localStorage | 4 | 3.5 | 8 | 10.50 | 4 |
sessionStorage | 5 | 2 | 8 | 10.50 | 4 |
globalStorage | Not supported | 2-13 | Not supported | Not supported | Not supported |
Feature | Android | Firefox Mobile (Gecko) | IE Phone | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|
Basic support | ? | ? | ? | ? | iOS 3.2 |
All browsers have varying capacity levels for both local- and sessionStorage. Here is a detailed rundown of all the storage capacities for various browsers.
Note: since iOS 5.1, Safari Mobile stores localStorage data in the cache folder, which is subject to occasional clean up, at the behest of the OS, typically if space is short.