Często zachodzi potrzeba zapisania pewnych danych w przeglądarce klienta aby przyśpieszyć działanie serwisu bądź mieć możliwość wykorzystania tych danych po ponownym wejściu odwiedzającego na stronę. Można w tym celu wykorzystać ciasteczka, jednak ze względu na niewielki rozmiar danych, które można tam zapisać nie są one zbyt efektywnym sposobem przechowywania danych po stronie klienta. Znacznie lepszym sposobem jest skorzystanie z obiektów do tego przeznaczonych czyli globalStorage w przeglądarce Firefox 2 i userData w przeglądarce Internet Explorer 5+.
globalStorage w Firefox 2
W przypadku przeglądarki Mozilla Firefox 2 mamy do dyspozycji obiekty sessionStorage i globalStorage. Oba obiekty umożliwiają zapisywanie dowolnych danych z pamięci przeglądarki z tą różnicą, że pierwszy z nich usuwa dane po wygaśnięciu sesji czyli po zamknięciu okna przeglądarki a w przypadku drugiego okres ważności danych jest nieskończony. Ze względu na przydatność zajmę się tylko obiektem drugim czyli globalStorage. Maksymalna ilość danych w nim zapisanych wynosi 5 MB i właśnie tyle mamy do wykorzystania. Dane zapisywane są w pliku webappsstore.sqlite w katalogu profilu Firefoksa. Wykorzystując obiekt globalStorage należy zdefiniować domenę dla jakiej dane mają być dostępne. Można użyć zarówno pełnej nazwy domeny (np. bukox.pl), tylko końcówki domeny (np. pl) lub pustego ciągu oznaczającego, iż dane będą widoczne z każdej domeny. Przykład użycia:
JavaScript:
-
store = globalStorage['bukox.pl'];
-
// zapis danych do obiektu
-
store.addItem('zmienna','wartosc');
-
-
// odczyt danych z obiektu
-
alert(store.getItem('zmienna').value);
-
-
// usuniecie danych z obiektu
-
store.removeItem('zmienna');
Więcej o obiektach storage w FF można znaleźć na stronie:
http://developer.mozilla.org/pl/docs/DOM:Storage
a specyfikacja DOM obiektu znajduje się pod adresem:
http://www.whatwg.org/specs/web-apps/current-work/#storage.
userData w Internet Explorer
Dla przeglądarki Internet Explorer począwszy od wersji 5 istnieje model userData, który także umożliwia zapisywanie danych użytkownika do pamięci przeglądarki. Rozmiar możliwych do zapisania danych jest zależny od strefy zabezpieczeń. Dla strefy internetu wynosi od 1 MB dla domeny i 128 KB dla dokumentu. Przykład użycia:
Najpierw należy wstawić dowolny znacznik, nadać mu identyfikator i odpowiedni styl:
HTML:
-
<div id="globalStore" style="behavior: url(#default#userdata)"></div>
Następnie poprzez zwykłe nadanie atrybutu można dodać zmienną i wartość do obiektu:
JavaScript:
-
// zapis danych do obiektu
-
globalStore.setAttribute('zmienna','wartosc');
-
globalStore.save('cache');
-
-
// odczyt danych z obiektu
-
globalStore.load('cache');
-
alert(globalStore.getAttribute('zmienna'));
-
-
// usuniecie danych z obiektu
-
globalStore.load('cache');
-
globalStore.setAttribute('zmienna','');
-
globalStore.save('cache');
Więcej informacji o obiekcie userData w IE można znaleźć pod adresem:
http://msdn2.microsoft.com/en-us/library/ms531424.aspx.
Przykłady użycia można znaleźć na stronach: http://www.webreference.com/js/column24/userdata.html i http://www.eggheadcafe.com/articles/20010615.asp.
Dla innych przeglądarek póki co nie można wykorzystać podobnych mechanizmów i pozostaje jedynie skorzystanie z ciasteczek lub ograniczenie funkcjonalności tylko do dwóch powyższych. Ze względu na fakt, iż obiekt storage stanowi część specyfikacji DOM można mieć nadzieje, że w najbliższym czasie także pozostałe przeglądarki zostaną wyposażone w obsługę obiektu storage.
Mechanizm cache opisany powyżej umożliwia przechowywanie danych po stronie klienta i ich odczyt nawet po ponownym uruchomieniu przeglądarki. Dzięki temu można stworzyć aplikację internetową, która może działać całkowicie offline. Wystarczy, że podczas normalnej pracy online dynamiczne dane są zapisywane do cache'u a po rozłączeniu z internetem dane są z niego pobierane. Dodatkowo operacje modyfikujące także mogą zostać zapamiętane i po przywróceniu połączenia z internetem dane mogą zostać zsynchronizowane z serwerem.
Poniżej znajduje się kod kompletnej klasy implementującej cache po stronie klienta działający zarówno w IE5+ jak i FF2, który automatycznie tworzy ukrytą warstwę (dla IE) oraz umożliwia kontrolę okresu ważności zapisanych danych.
JavaScript:
-
var TCache = function(domain) {
-
if(typeof globalStorage != "undefined") {
-
// jesli FF
-
if(typeof domain == "undefined") {
-
var domain = location.host;
-
}
-
this.storage = globalStorage[domain];
-
} else {
-
// jesli IE
-
if(!document.getElementById('globalStore')) {
-
// dynamicznie dodanie warstwy dla cache
-
var storageObj = document.createElement('DIV');
-
storageObj.id = 'globalStore';
-
storageObj.style.behavior = 'url(#default#userdata)';
-
storageObj.style.display = 'none';
-
document.body.appendChild(storageObj);
-
}
-
this.storage = globalStore;
-
}
-
}
-
TCache.prototype = {
-
/**
-
* Magazyn danych
-
*
-
* @var object
-
*/
-
storage : null,
-
/**
-
* Funkcja zapisuje cache
-
*
-
* @param string name Nazwa zmiennej cache
-
* @param mixed data Dane do zapisania
-
* @param int expires Okres waznosci danych (w sek., domyslnie bez limitu)
-
* @return bool
-
*/
-
save : function(name, data, expires) {
-
if(typeof globalStorage != "undefined") {
-
// jesli FF
-
this.storage.setItem(name, data);
-
if(typeof expires != "undefined") {
-
var _this = this;
-
setTimeout(function(){this.remove(name)}, expires*1000);
-
}
-
return true;
-
} else if(typeof this.storage.XMLDocument != "undefined") {
-
// jesli IE
-
if(typeof expires != "undefined") {
-
var oTimeNow = new Date();
-
oTimeNow.setSeconds(oTimeNow.getSeconds() + expires);
-
this.storage.expires = oTimeNow.toUTCString();
-
}
-
this.storage.setAttribute(name, data);
-
this.storage.save('cache');
-
return true;
-
} else {
-
return false;
-
}
-
},
-
/**
-
* Funkcja pobiera dane z cache
-
*
-
* @param string name Nazwa zmiennej cache
-
* @return mixed
-
*/
-
get : function(name) {
-
if(typeof globalStorage != "undefined") {
-
// jesli FF
-
if(this.storage.getItem(name)) {
-
var result = this.storage.getItem(name).value;
-
}
-
} else if(typeof this.storage.XMLDocument != "undefined") {
-
// jesli IE
-
this.storage.load('cache');
-
var result = this.storage.getAttribute(name);
-
}
-
return (result) ? result : null;
-
},
-
/**
-
* Funkcja usuwa zmienna z cache
-
*
-
* @param string name Nazwa zmiennej
-
*/
-
remove : function(name) {
-
if (typeof globalStorage != "undefined") {
-
// jesli FF
-
this.storage.removeItem(name);
-
return true;
-
} else if(typeof this.storage.XMLDocument != "undefined") {
-
// jesli IE
-
this.storage.load('cache');
-
this.storage.setAttribute(name, '');
-
this.storage.save('cache');
-
return true;
-
} else {
-
return false;
-
}
-
}
-
}
Sposób użycia:
JavaScript:
-
var cache = new TCache();
-
cache.save('imie','adam');
-
alert(cache.get('imie'));