Browseropslag voor HTML5-apps

Jarenlang was een van de belangrijkste voordelen van het schrijven van desktoptoepassingen de gemakkelijke toegang tot lokale opslag op de clientcomputer. Webontwikkelaars hebben te maken gehad met het onvermogen om gegevens van de computer van de klant te bewaren en op te halen voor een lange tijd, maar het ziet ernaar uit dat dit binnenkort kan veranderen. Je zou zelfs denken dat het al heeft na het lezen van dit artikel. Ja, ik ga de oorsprong van aanhoudende gegevens over de clientcomputer bespreken en u vervolgens laten kennismaken met de Web Storage-standaard.

De meeste webontwikkelaars weten dat de enige vorm van lokale opslag die we van een webbrowser kunnen verwachten, de vorm van cookies heeft. Nou, niet helemaal. De wens om gegevens op de clientcomputer op te slaan is geen nieuw concept en werd niet bedacht bij het maken van HTML5-specificaties. Nog verbazingwekkender is dat Microsoft een werkende implementatie heeft ontwikkeld als onderdeel van de IE6-functieset. Ze noemden het gebruikersgegevens en het garandeerde in wezen minstens 640 KB aan lokale ruimte per domein, afhankelijk van het beveiligingsbeleid van IE dat door de gebruiker is ingesteld. Dat lijkt volgens de huidige standaard misschien heel weinig ruimte, maar als we het vergelijken met de maximale 4KB-ruimte waarover Cookies beschikken, is de verbetering merkbaar.

Wat is er mis met cookies?

Een aantal dingen. Het grootste probleem met cookies is dat ze bij elk HTTP-verzoek heen en weer worden verzonden tussen de browser en de server. Dit is geen gewenst gedrag, omdat ontwikkelaars vaker dan niet de lokale gegevens meer dan eens naar de server willen verzenden, als ze überhaupt al aanwezig zijn. Cookies geven ontwikkelaar geen keuze.

Zoals we eerder al zeiden, kunnen cookies maximaal 4 kB aan gegevens opslaan. Het zijn niet veel gegevens, maar 4 KB is voldoende om paginaverzoeken merkbaar te vertragen.

Cookies worden ook heen en weer gescrold tussen de client en de server in duidelijke tekst. Daarom is de enige manier om ze te beschermen, door de gegevens te versleutelen tijdens de communicatie met de backend-server met SSL (Secure Socket Layer). De meeste websites op internet gebruiken echter geen SSL, waardoor de opslag open staat voor afluisteren.

Er zijn nog andere problemen die cookies minder handig maken. Idealiter willen ontwikkelaars de mogelijkheid hebben om grote hoeveelheden gegevens op de clientcomputer aan te houden en hoeven die gegevens niet steeds opnieuw naar de server te verzenden.

Wat zijn de alternatieve oplossingen?

Tot nu toe hebben we niet gesproken over niet-standaard oplossingen voor aanhoudende gegevens op de clientcomputer. Toen Adobe (toen bekend als Macromedia) ontwikkelaars Flash Player 6 uitbrachten, moesten ook zij hetzelfde probleem aanpakken. In 2002 introduceerde Flash Player 6 een nieuwe functie met de naam Lokaal Gedeeld Object of vaker bekend als Flash-cookies om effectief dezelfde mogelijkheden te introduceren als standaard HTTP-cookies voor Flash-films en -sites. Met lokaal gedeeld object konden ontwikkelaars standaard 100 KB aan gegevens op de clientcomputer opslaan.

De tweede oplossing is de implementatie door Google van lokale opslag als onderdeel van de Gears-plug-in voor webbrowsers. Gears was (en ik vertel je waarom ik gebruik was in een oogwenk) de combinatie van meerdere ontbrekende en nuttige functies die nodig zijn voor het ontwikkelen van Rich Internet Applications (RIA). De lokale opslag van Gears was gebaseerd op de minder populaire Web SQL-specificatie die profiteerde van SQLite. Je raadt het goed, Gears gaf ontwikkelaars een volledig opgeblazen SQL-database om een ​​onbeperkte hoeveelheid gegevens op de clientcomputer aan te houden.

De ontwikkelaars van Ajax Massive Storage System (AMASS) maakten van deze gelegenheid gebruik en ontwikkelden een JavaScript-bibliotheek van derden waarmee standaard-HTML-sites konden profiteren van de functie Lokaal gedeeld object in Flash of de Gears-plug-in om gegevens over de client machine. De dojo JavaScript-bibliotheek kan ook de beschikbaarheid van lokale opslagmechanismen detecteren (bijvoorbeeld Google Gears, lokaal gedeeld object, enz.) En biedt een uniforme interface voor aanhoudende gegevens in verschillende webbrowsers..

Terug naar waarom ik zei dat Gears 'was' in plaats van 'still is': dat is omdat Google onlangs heeft aangekondigd dat ze verdere ontwikkeling van de Gears-plug-in zullen laten vallen ten gunste van HTML5 en de Web Storage-specificatie die in deze zelfstudie wordt gepresenteerd.

HTML5- en webopslagspecificaties

Nu de geschiedenisles voorbij is, gaan we meer leren over Web Storage en duiken we in een code om het beter te begrijpen. De eenvoudigste manier om Web Storage te beschrijven, is de mogelijkheid om gegevens op de clientcomputer in de vorm van één sleutel voor één waarde aan te houden. Dit lijkt erg op hoe associatieve arrays worden gebruikt:

 "De sleutel": "De waarde"

Lokale opslag is ontworpen om native ondersteund te worden door webbrowsers. Dit betekent geen bibliotheken van derden meer en knoeien met Flash. Verrassend genoeg was Web Storage een van de meer succesvolle specificaties in termen van acceptatie door moderne browsers. In feite ondersteunen bijna alle moderne browsers Webopslag, waaronder:

  • Internet Explorer 8+
  • Firefox 3.5+
  • Safari 4+
  • Opera 10.5+
  • iPhone Safari
  • Android webbrowser

Hoewel Web Storage soortgelijke functionaliteit als Cookies wil bieden, is het verder verfijnd om geen van hun negatieve kenmerken te bevatten. Webopslag maakt bijvoorbeeld het mogelijk om tot 5 MB aan gegevens door te laten, een aanzienlijke toename van de ruimte in vergelijking met hoeveel gegevens kunnen worden opgeslagen in een cookie. Ook zullen aanhoudende gegevens met behulp van Web Storage er niet toe leiden dat die gegevens met elke paginavraag naar de server-backend worden verzonden. Dit verhoogt de prestaties aanzienlijk. Volgens de Web Storage-specificatie vervallen webbrowsers alleen de persistente gegevens van de lokale machine als de gebruiker hierom vraagt ​​en vermijden ze altijd gegevens te verwijderen terwijl een script dat toegang tot die gegevens kan krijgen, actief is.

Webbrowsers stellen webopslag bloot via de lokale opslag object in JavaScript. Een eenvoudige manier om te bepalen of een webbrowser Webopslag kan ondersteunen, is door deze JavaScript-code uit te voeren:

 var webStorageSupported = ('localStorage' in venster) && window ['localStorage']! == null;

Volgens de W3C-specificatie voor webopslag, de lokale opslag object implementeert de volgende set methoden en eigenschappen vanuit de Storage-interface. Laten we elk van deze methoden en eigenschappen bekijken om uit te zoeken wat ze doen en hoe ze kunnen worden gebruikt:

 interface Opslag alleenleesbaar lang lengte; leegte setItem (String-toets, Objectgegevens); Voorwerp getItem (String-toets); leegte removeItem (String key); leegte duidelijk(); Draad sleutel (lange index); ; 

De lengte eigendom is erg handig. Het geeft het aantal sleutel / waardeparen dat momenteel is opgeslagen terug naar Lokale opslag onder het domein dat momenteel wordt geopend:

 alert (localStorage.length);

Als er geen sleutel / waarde-paren eerder in de lokale opslag zijn opgeslagen, geeft het bovenstaande script een waarschuwingsvenster weer met "0" als bericht, anders is het bericht het aantal persistente sleutel / waardeparen.

De setItem (sleutel, waarde) methode slaat eenvoudig een nieuw item op de lokale computer op. Om de sleutel op te slaan naam met de waarde arman we kunnen dit script uitvoeren:

 localStorage.setItem ('name', 'arman');

Om die sleutel te verzekeren naam werd echt opgeslagen in de lokale opslag met de waarde arman we moeten de. gebruiken getItem (sleutel) methode. De getItem methode accepteert eenvoudigweg een sleutel en doorzoekt de lokale opslag om een ​​overeenkomende sleutel te vinden en retourneert vervolgens de waarde ervan.

 localStorage.setItem ('name', 'arman'); var value = localStorage.getItem ('name'); alert (waarde);

Als u het bovenstaande script uitvoert, ziet u een waarschuwingsvenster met het woord arman verschijnen op het scherm, waarmee wordt bevestigd dat we met succes een nieuw sleutel / waarde-paar hebben opgeslagen in de lokale opslag. Sinds de lokale opslag object gedraagt ​​zich vergelijkbaar met associatieve arrays, we kunnen het bovenstaande script vereenvoudigen om er zo uit te zien en het zal nog steeds precies hetzelfde functioneren:

 localStorage ['name'] = 'arman'; var value = localStorage ['name']; alert (waarde);

Laten we naar de removeItem (sleutel) methode. Deze methode is ontworpen om een ​​eerder opgeslagen sleutel / waarde-paar uit de lokale opslag te verwijderen. Als de sleutel niet bestaat, doet deze methode gewoon niets. Het volgende codevoorbeeld toont het gebruik van de Verwijder voorwerp methode:

 localStorage.setItem ('name', 'arman'); localStorage.removeItem ( 'name'); var value = localStorage.getItem ('name'); alert (waarde);

Wanneer het bovenstaande script wordt uitgevoerd, ziet u een waarschuwingsvenster met de waarde nul in het waarschuwingsvenster. De ... gebruiken naam sleutel, maakt het bovenstaande script eenvoudig een nieuw sleutel / waarde-paar en verwijdert het onmiddellijk uit de lokale opslag. Vervolgens wordt een ongeldige waarde geretourneerd bij het benaderen van de lokale opslag met dezelfde naam sleutel.

Er zullen gelegenheden komen waarbij er behoefte is om de lokale opslag volledig te zuiveren en met een schone lei te beginnen. De duidelijk() methode is precies voor dat doel ontworpen. Met deze methode leegt u automatisch alle eerder opgeslagen sleutel / waardeparen uit de lokale opslag. Als er geen items zijn, verandert er niets.

 localStorage.setItem ('name', 'arman'); localStorage.setItem ('name', 'smith'); localStorage.setItem ('naam', 'frank'); alert (localStorage.length); localStorage.clear (); alert (localStorage.length);

Hoewel het bovenstaande script drie nieuwe sleutel / waarde-paren maakt (zoals blijkt uit de eerste waarschuwing), verwijdert de aanroep van de methode clear () alle vermeldingen. Vervolgens zal het tweede waarschuwingsvenster een "0" -bericht weergeven.

De laatste methode die we moeten bekijken, is de key (index) methode. Met deze methode wordt de naam van een sleutel opgehaald op basis van de indexparameter. lokale opslag onderhoudt een op 0 gebaseerde lijst van alle items in zichzelf. Daarom hebben we voor het benaderen van de eerste sleutel uit de lokale opslag 0 nodig als de index zoals geïllustreerd in dit script:

 localStorage.clear (); localStorage.setItem ('leeftijd', 5); alert (localStorage.key (0));

Wanneer het bovenstaande script wordt uitgevoerd, zou er een waarschuwingsvenster moeten verschijnen met het bericht "leeftijd". Merk op hoe in het bovenstaande voorbeeld de eerste regel code de lokale opslag wist. Dit is om te zorgen dat we beginnen met een schone lei. Een andere nuttige toepassing van de sleutel() methode is in combinatie met de lengte eigendom. Als u bijvoorbeeld alle sleutel / waardeparen van de lokale opslag wilt ophalen zonder de sleutels van tevoren te kennen, kunnen we een script schrijven zoals het volgende:

 localStorage.clear (); localStorage.setItem ("title", "Mr."); localStorage.setItem ("fullname", "Aaron Darwin"); localStorage.setItem ("age", 17); localStorage.setItem ("height", 182.5); for (var i = 0; i < localStorage.length; i++)  var keyName = localStorage.key(i); var value = localStorage.getItem(keyName); alert(keyName + " = " + value); 

In het bovenstaande script wist onze code eerst en voegt vervolgens vier nieuwe sleutel / waarde-paren toe aan de lokale opslag. Dan gebruikt het de lengte eigendom in een Voor loop om de sleutel uit te werken voor elk sleutel / waarde-paar. Bij elke iteratie van de lus wordt de sleutel toegewezen aan de keyname variabele die vervolgens wordt doorgegeven aan de getItem () methode om de waarde ervan op te halen.

De subtiliteiten

Bij toegang tot gegevens met een sleutel die niet bestaat in de lokale opslag, in plaats van een uitzondering, nul waarde wordt altijd geretourneerd. Dit maakt het moeilijk om te weten of de waarde van de sleutel is nul of de sleutel bestaat gewoon niet in de lokale opslag.

De tweede om over te praten is het setItem (sleutel, waarde) methode. We weten dat we elk type waarde kunnen doorgeven aan de setItem () methode voor de waarde parameter, maar dat is niet helemaal waar. In JavaScript kunnen we creëren Beeld voorwerpen. De huidige implementatie van Web Storage maakt echter alleen persistente primitieve typen mogelijk, zoals Draad, Boolean, Geheel getal en Vlotter types. Daarom kunnen we verwachten dat het volgende script een uitzondering en crash veroorzaakt:

 var imageObject = new Image ("http://www.google.com/logo.gif"); localStorage.setItem ("image", imageObject);

Bovendien, ook al kunnen we besparen Boolean, Geheel getal en Vlotter typen, de onderliggende weergave van deze typen valt terug op de Draad type. Dit betekent ongeacht het type waarde dat aan de. Wordt doorgegeven setItem () methode, de getItem () methode retourneert altijd een waarde van het type String. Laten we een voorbeeldscript bekijken:

 var integerVariable = 34; localStorage.setItem ("age", integerVariable); var newVariable = localStorage.getItem ("age"); alert (typeof (nieuwVariabel) == "nummer");

In het bovenstaande script, uiteindelijk de waarde van de integerVariable wordt opgeslagen als tekenreeks. Daarom, wanneer we het type newVariable inspecteren nadat het de waarde heeft gekregen van de lokale opslag, is het niet langer een integer-type en daarom zal de vergelijkingsinstructie evalueren naar false. In dergelijke situaties moeten we het handige gebruiken parseInt (String) en parseFloat (String) functies voor conversie. Er is GEEN functie om te analyseren Boolean gegevenstype, dus we moeten gewoon de opgehaalde waarde vergelijken met "true" of "false" strings.

Ten slotte, om de vergelijkende verklaring in het bovenstaande script te evalueren waar, we moeten onze code aanpassen om de parseInt () functie te gebruiken zoals getoond in het volgende script:

 var integerVariable = 34; localStorage.setItem ("age", integerVariable); var newVariable = parseInt (localStorage.getItem ("age")); alert (typeof (nieuwVariabel) == "nummer");

Wanneer het bovenstaande script wordt uitgevoerd, wordt het type waarde opgeslagen in de newVariable zal zijn Geheel getal. Vervolgens zal de vergelijkingsverklaring evalueren naar waar.

Wanneer de persistente gegevens het 5MB-quotum bereiken, bieden webbrowsers niet de mogelijkheid om meer ruimte in de lokale opslagruimte te vragen. Ze gooien in plaats daarvan de QUOTA_EXCEEDED_ERR uitzondering om het script te melden dat er geen ruimte meer is. De eenvoudigste manier om met deze uitzondering om te gaan is om de uitzondering te vangen en de gebruiker op de hoogte te stellen van het probleem.

Als alternatief voor het vangen van de uitzondering, kan het script een aantal sleutel / waarde-items uit de lokale opslag verwijderen om ruimte vrij te maken voor nieuwe paren.

Ten slotte wordt, wanneer het document rechtstreeks van de schijf wordt opgevraagd en niet van een webserver, de lokale opslagruimte gewist telkens wanneer u van de pagina weg navigeert.

Web Storage-evenementen

Met Web Storage Standard kunnen scripts worden gewaarschuwd wanneer andere delen van de code vermeldingen van de lokale opslag toevoegen, bijwerken of verwijderen. Dus, wanneer er iets verandert in de lokale opslag, a Opslag evenement gaat vuren. In het geval van het verwijderen van een item met een niet-bestaande sleutel, wordt er echter geen evenement geactiveerd. Dit komt omdat er niets verandert in de lokale opslag. Helaas hebben mijn tests aangetoond dat Webkit-browsers (zoals Safari en Chrome) momenteel niet worden geactiveerd Opslag evenementen zoals beschreven door de Web Storage-specificatie. Internet Explorer, Firefox en Opera-browsers gedragen zich zoals verwacht.

Een lokale opslaggebeurtenis kan niet worden geannuleerd. Het enige doel hiervan is om de gebruikerscode te melden van een wijziging die is opgetreden in de lokale opslag.

In het volgende script ziet u hoe u naar wijzigingen in de lokale opslag luistert door een gebeurtenishandler te registreren die telkens een a wordt genoemd Opslag evenement is ontslagen:

 if (window.addEventListener) window.addEventListener ("storage", handleStorageChange, false);  else window.attachEvent ("onstorage", handleStorageChange);  function handleStorageChange (event) alert ("Er is iets veranderd in de lokale opslag"); 

Aangezien geen enkele versie van Internet Explorer (met uitzondering van openbare versie van versie 9) het DOM Level 2 gebeurtenisafhandelingssysteem ondersteunt, ondersteunt het attacheEvent () methode moet worden gebruikt om gebeurtenishandlers te registreren.

De evenement argument is handig omdat het informatie over veranderingen in de lokale opslag bevat. Het houdt zich aan de StorageEvent interface:

 interface StorageEvent: Event readonly String sleutel; readonly Object OldValue; alleen-lezen object nieuwe waarde; readonly String url; ; 

De sleutel property identificeert welk sleutel / waarde-paar is gewijzigd. De OldValue en de nieuwe waarde eigenschappen gedragen zich zoals hun naam doet vermoeden. Dat wil zeggen, ze bevatten respectievelijk de vorige en de nieuwe waarde voor de sleutel.

eindelijk, de url eigenschap bevat het adres van het document waarvoor de lokale opslag zojuist is gewijzigd. Vanwege meerdere implementatie-iteraties van de Web Storage-specificatie in sommige webbrowsers echter url eigendom kan worden geïmplementeerd als uri. Daarom is het beter om eerst de url eigendom en vervolgens uri voor het geval de url eigenschap is niet gedefinieerd.

demonstratie

Na het lezen van dit veel, ik meestal graag een voorbeeld zien voordat ik geloof het allemaal. Net als ik, ben ik er zeker van dat velen van u ook graag een werkend voorbeeld zouden zien. Dat is geen probleem, omdat ik een klein script heb voorbereid dat eenvoudigweg het gebruik van de webopslagstandaard in een werkende toepassing demonstreert.

Het is zo gemaakt dat het ook kan worden getest met behulp van iPhone Safari en de Android-webbrowser. Het idee is om de browser te laten onthouden welke vakjes zijn geopend voordat de lokale opslag wordt gebruikt. Ik laat je achter met deze code om mee te spelen:

         

Web Storage Demo

Deze pagina was ontworpen om eenvoudig het gebruik van webopslag in moderne browsers te demonstreren. In dit voorbeeld blijven vakken die nog niet zijn aangeklikt zwart. Zodra u op een zwarte doos klikt, wordt de echte kleur onthuld. De browser onthoudt echter op welke vakjes wordt geklikt, zelfs wanneer u weg navigeert van deze pagina. Ga door, probeer het eens.