Valójában itt nem pontos leírással szeretnék szolgálni, hanem inkább a lehetőségekről írnék. Ezzel a témával akkor kezdtem el foglalkozni, amikor az Offline alkalmazásokról volt volt szó egy korábbi meetupon, és Yaanno pont erről a témáról tartotta a bemutatóját.
Első körben jó tisztázni, hogy miről is van szó: Gondolom minden webfejlesztő találkozott olyan esettel, amikor a kliens oldalon kellett adatot tárolni, legyen az csak egy a felhasználó azonosítására szolgáló titkos kulcs, vagy több a kliens oldali megjelenést befolyásoló adat. Ezek tényleg csak alap esetek, ahol az egyszerűbb megoldások a célravezetőek, ám vannak olyan offline alkalmazások, amik már komolyabb adattárolást igényelnek (például böngésző kiegészítők). Aki valaha is léptetett be felhasználót egy oldalra, az biztosan használta már a munkameneteket szerver szinten. Bár ez tényleg szerver oldali, mégis hagy nyomot a kliens oldalon. Itt kerülnek képbe a sütik, amiket már kifejezetten kliens oldalon használunk.
Ezek egyszerűen kezelhetők egy-egy adat tárolására, meghatározott ideig. Munkamenet (Session) esetén meghatározhatjuk hogy ezt az időt, ám a böngésző bezárásával a munkamenet lezárul. A sütik (Cookie) esetén is meghatározhatjuk az élettartamot, azonban itt megmaradnak az adatok a böngésző bezárása után is.
Valójában a munkamenet azonosítója is egy sütiben kerül tárolásra, melynek neve munkamenet süti (session cookie). Az ilyen adattárolást használják a legtöbb webáruháznál is, ahol a kosár tartalmát kell tárolni és elérhetővé tenni a szerver számára.
Azonban vannak olyan esetek, amikor szeretnénk adatot tárolni kliens oldalon, ám nincs szükség, hogy ezt az adatot elérje a szerver. Például ha az alkalmazásunk felülete testre szabható elemeket tartalmaz. Ekkor felesleges elküldeni minden lekéréskor a felület beállításait a szervernek, ahol ezzel az adattal nem is foglalkozunk (persze lehet olyan alkalmazásunk ahol a felhasználói beállításokat szerveren kell tárolni, de jelen példa az egyszerűségre törekedett) és csak lassítja a betöltési időt.
Tehát szükségünk lenne egy olyan adattárolásra, amit csak a kliens ér el.
Ekkor jön képbe a LocalStorage nevű módszer, ami egyszerűen fájlban tárolja az adatokat. Használata egyszerű, javascript segítségével tudunk neki értéket adni és az értéket kinyerni. Hasonlóképpen kell kezelnünk, mint a tömböket, csak a kulcsnak itt az adatunk azonosítóját kell megadnunk, amit szabadon választhatunk. Jöjjön itt egy-két példa:
var foo = localStorage.getItem("bar");
// ...
localStorage.setItem("bar", foo);
vagy
var foo = localStorage["bar"];
// ...
localStorage["bar"] = foo;
Én ez utóbbit szoktam használni. A LocalStorage szerencsére egy olyan eszköz, melyet a modern böngészők (így az ie 8 és frissebb változatok) képesek kezelni, mivel ez a HTML5 szolgáltatásai közé tartozik. Igaz a fentebb említett sütis megoldást a régebbi böngészők is támogatták.
Aki részletesebben szeretne olvasni a LocalStorage használatáról, annak ajánlom a diveintohtml5 és a w3 ide vonatkozó részét.
A másik igen hasznos ám sajnos elhanyagolt adattárolási módszer a böngésző részét képző adatbázis, mely működése az SQLite-éval azonos. Ez az alkalmazásunkra nézve annyit jelent, hogy javascript segítségével létrehozhatunk egy adatbázis kapcsolatot, táblákkal, melyben tárolhatjuk az adatokat. Az adatok rögzítése, illetve minden művelet a megszokott SQL parancsok segítségével lehetséges. Ennek a neve WebSql és sajnos kevés böngésző kezeli (Chrome, Opera, Safari), sajnos ezen kevés böngésző között nem szerepel a Firefox, mivel az az Oracle által fejlesztett Indexed DB támogatása mellett döntött (WebSQL utódja).
Azt, hogy miért hasznos SQL-ben tárolni az adatokat, szerintem felesleges is kifejteni, hiszen tudjuk, hogy nagy mennyiségű adat tárolása és feldolgozása kliens oldalon mennyire nehézkes tud lenni.
De hogyan is működik az egész? Első használat esetén létre kell hoznunk egy kapcsolatot, mely nem igényel sok beállítást, révén hogy csak nevet kell adnunk az adatbázisunknak és meg kell határozzuk a méretét. Itt érdekességként említem, hogy a böngészők nagyméretű adatbázis létrehozása előtt engedélyt kérhetnek a felhasználótól, de kisebb 2-5 MB-s adatbázisokat kérdés nélkül létrehoznak.
var db = openDatabase('test', '1.0', 'test database', 2 * 1024 * 1024);
Gondolom sokaknak feltűnt, hogy a létrehozáshoz használt függvény egyben a megnyitást is jelenti. Azaz a függvény vagy létrehozza, vagy megnyitja, ha létezik már az adatbázisunk. Hasznos ez a működés, hiszen mentesülünk, hogy nekünk kelljen ezt kezelni. Elsőnek az adatbázisunk nevét kell megadni, majd a verziószámot és opcionálisan a leírást, majd a méretet, melyet ha nincs megadva böngésző által meghatározott alapértelmezett értékre állít be a függvény.
db.transaction(function (tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS foo (id unique, text)');
tx.executeSql('INSERT INTO foo (id, text) VALUES (1, "proba")');
});
A megnyitáskor visszakapott objektum segítségével aztán műveleteket végezhetünk az adatbázisunkon. Ha szeretnénk adatokat változókból elmenteni, használhatjuk a behelyettesítéses módszert, mely a kérdőjelek helyére rakja be a megfelelő adatot, csak a sorrendre kell figyelni.
db.transaction(function (tx) {
tx.executeSql('INSERT INTO foo (id, text) VALUES (?, ?)', [id, userValue]);
});
Itt az executeSql második paraméterében kell megadni az értékeket abban a sorrendben, ahogy a kérdőjelek helyére szeretnénk behelyettesíteni.
db.transaction(function (tx) {
tx.executeSql('SELECT * FROM foo', [], function (tx, results) {
var len = results.rows.length, i;
for (i = 0; i < len; i++) {
alert(results.rows.item(i).text);
}
});
});
Ahhoz hogy adatot nyerjünk ki, a műveleteknél is használt executeSql függvényt kell használnunk, azonban itt már a többi funkciójára is szükség lesz. Első paraméterként a futtatandó SQL parancsot, másodiknak egy üres tömböt és harmadikként egy callback függvényt, amiben az eredmények kilistázását csinálhatjuk. A result objektumként adja vissza az összes adatot, a lekérdezésünk alapján soronként. Tehát az összes sort a result.rows segítségével érjük el, melyből a sorokat az item(index) segítségével érjük el, azaz az első sort result.rows.item(0) módon. Ebből a mezőnevek segítségével nyerhetjük ki a szükséges adatot. A text mező tartalmát az első sorból a result.rows.item(0).text használatával.
Ezzel kapcsolatban szintén jó leírás található a fentebb már említett diveintohtml5 oldalon és Remy Sharp tollából.
A WebSql mellett van még lehetőség WebSimpleDB ,vagy Indexed DB, teljes nevén Indexed Database API használatára. Fejlesztője az Oracle és a WebSQL utódjának szánják, a w3c ezért inkább ezt az irányt viszi tovább, ami miatt a WebSQL-t dobták. Egyenlőre csak a Firefox és a Chrome támogatja ezt az adattárolási módot. Használata bonyolultabb ugyan, mint a fentebb bemutatott WebSQL, ám ez is viszonylag kevés kódolást igényel. Akit érdekel látogasson el a w3 oldalára, vagy olvassa el a Mozilla Hacks cikkét, vagy a html5rocks oldal hogyan használjuk írását.
Most hogy tudjuk milyen módon tárolhatunk adatokat a kliensen már csak azt kéne tudnunk melyiket válasszuk. Ha tudjuk hogy alkalmazásunk csak Chrome alatt lesz használva (például Chrome App-ként vagy kiegészítőként), akkor választhatunk a lehetőségek közül, hisz minden támogatva van. Én például az egyszerűbb beállításokat LocalStorage-ben tárolnám, a felhasználó által rögzített (vagy lekért) adatokat meg valamelyik adatbázisban. Személy szerint a WebSQL egyszerű használata miatt én ezt választottam egy hírolvasó kiegészítés fejlesztésénél. Viszont ahol tudjuk hogy sokféle böngészőre kell felkészülni felmerülhet a kérdés: mit áldozhatunk be a teljes böngészőfüggetlenségért, és mennyire kell visszanyúlnunk az időben, azaz támogassuk-e például az IE6-ot. Ezt mindenki maga döntse el, de érdemes figyelembe venni, hogy a Google (és sokan mások) maximum a legfrissebb verzió mínusz 1-2 kiadást támogatnak. Folyt köv…

küldés...