AJAX fejlesztés - kommunikáció
Folytatva korábbi bejegyzéseimet, az alapok és a megjelenítés után szeretnék egy kicsit írni a kommunikációról is a webalkalmazás és a szerver között. Egy "igazi" webalkalmazásnál (ahol egy összetett felületünk van, s a lényeg a böngészőnkben fut, nem pedig a szerveren) alapvetően két formátum merülhet fel: az egyik a JSON, a másik pedig az XML - de a többi lehetőségre is kitérek röviden.
A dolog egyébként úgy tűnik, hogy nem csak engem foglalkoztat, hiszen pont egy hasonló írást láthattunk Szalai Ferenc tollából is, én is hasonlókat fogok írni, mint ő.
Lássuk az alapokat: ha a kliens (böngésző) és a szerver (szerver oldali program) kommunikál egymással, mindenképpen kell választanunk valamilyen protokollt, és valamilyen adatformátumot. A protokoll kiválasztása esetünkben egyértelmű, mivel nem nagyon támogat mást a JavaScript és maga a böngésző: ez pedig a HTTP. A kérdés valójában csak az, hogy ezen milyen adatokat küldjünk a kliens felé.
A következő adatformátumok jöhetnek szóba:
Mindegyik formátum másra lehet jó, máskor használható, az alkalmazás típusától nagyban függhet, hogy melyik az ideális. Arról, hogy milyen alkalmzástípusok vannak, talán majd még születik egy bejegyzésem, röviden: különválaszthatóak azok, ahol inkább a szerver oldalon, s azok, ahol inkább a kliens oldalon van a logika. A hangsúly persze az inkább szón van, lehet a működés teljesen vegyes is (bár nem feltétlenül célszerű keverni).
Kezdem hátulról - nézzük a JavaScript kód alapú kommunikációt. Ebben az esetben utasítások soráról beszélünk, például a szerver a kliensnek a következő kis programot küldi le:A program egy adott
A következő lehetőség a HTML formátum. Itt gyakorlatilag arról van szó, hogy a szerver egy oldalrészletet küld a kliensnek, amit az egy az egyben megjelenít (egy adott oldalrészletet lecserélve, kiegészítve). Ilyet használtam a web.zin.hu (és társai) esetén a lapozáshoz - ez egy nagyon egyszerű megoldás, és kiválóan is tud működni. Van neki még egy hatalmas előnye is: segítségével könnyen beilleszthető egy kis AJAX feeling meglévő keretrendszerünkbe, amennyiben az támogatja az oldal egyes részeinek külön "renderelését". Ez a megoldás leginkább lapozás, szűrés, frissítés és ezekhez hasonló tevékenységekhez lehet hasznos, ahol a kliensnek sok dolga nincs. Itt a kliens oldali logika az előző megoldáshoz hasonlóan szintén a nullához közelít. A HTML leküldését szokás AJAH (Asynchronous Javascript and HTML) néven illetni.
Mind a két eddig megoldásra jellemző, hogy inkább a hagyományos weblapok felturbózására, gördülékenyebben történő működtetésére lehet kiváló megoldás, és hogy viszonylag nagyobb sávszélességet igényel. A JavaScript csak egy kiszolgáló, a megjelenítési réteghez tartozó eszköz, még akkor is, ha összetettebb tevékenységeket is végez. Lehet persze okosan elkezdeni turbózni ezeket a megoldásokat, például gyorsítótárazni a kapott HTML-t, és nem kérni le még egyszer, de alapvetően nem fog a helyzet megváltozni. Ha a JavaScriptbe logikát is szeretnénk csepmészni, akkor nem elég kódot vagy HTML-t küldeni neki, mindenképpen valamilyen adatleíró formátumot kell választani. Nos, erre alkalmas az XML és a JSON.
A JSON-ról magáról most nem írnék sokat, aki szeretne, utánanéz majd, hogy pontosan miről van szó. Röviden a lényeg: ez az a formátum, melyben JavaScriptben adatot írhatunk le, így az egyik hatalmas előnye, hogy a JavaScript számára közvetlenül feldolgozható. A közvetlenül feldolgozható azt jelenti, hogy natív változóként jelenik meg az adat, így egy ciklusnak része lehet (iteráció), közvetlenül megcímezhető és lekérdezhető (például
A JSON leküldésnek van egy hátránya, miszerint ha hatékonyak akarunk lenni, a leküldött adathalmazt egy
Ahogy írtam, ha a JSON segítségével megvan az adat, elég hatékonyan és gyorsan felhasználható, szinte bármire. Lehet benne a szerver felől parancsokat küldeni, lehet kis adatrészleteket, vagy akár teljes táblázatokat is. Sokan, sokféleképpen használják ezt a formátumot. Előnye minden bizonnyal az, hogy JavaScript műveletekkel könnyen feldolgozható, átalakítható, végrehajtható. Részemről használtam már parancsok átviteli közegeként egy IRC szerver felől, felhasználói beállítások lekérdezésére, tárolására, adatok leküldésére táblázatos adatok megjelenítéséhez, szűréséhez, stb.
A JSON-nak van egy JSONP nevű másik vállfaja, melynek segítségével távoli szerverekről is leszedhetünk adatokat. A trükk az, hogy valójában egy folyton változó JavaScript részletet töltünk le, egy
Térjünk át az XML-re. Az XML a böngészőkben futó JavaScript nyelvnek nem kifejezetten natív formátuma, mégis elmondható, hogy manapság már elég sok böngésző alapból támogatja így, vagy úgy, s hogy kialakultak egységes JS API-k a kezelésére. Az XML segítéségével szintén összetett adathalmazokat le tudunk küldeni a kliensnek, s azt kényünkre kedvünkre át is tudjuk alakítani XSLT segítségével, majd megjeleníteni. Az adat JavaScript segítségével is megcímezhető, így bármely részlethez hozzáférhetünk, és JavaScript logikát is vihetünk a dologba.
A JSON és XML formátum között van egy megközelítésbeli különbség. Ha főként megjeleníteni szeretnénk az adatokat különböző szempontok szerint, akkor az XML erre kiválóan alkalmas formátum lehet, hiszen XSLT használatával könnyen és gyorsan alakítható HTML-lé a letöltött adat. Az XML használata ott kezd kevésbé kényelmes lenni, amikor az XSLT beépített függvényei számára nem megoldható adatfeldolgozó logikát szeretnénk a programunkba építeni. Ha nagy mennyiségű adatot szeretnénk JavaScripttel kinyerni az XML-ből, akkor az elég lassú lesz ugyanis - vagy legalábbis nekem nem nagyon sikerült gyorsan megoldani ezt a feladatot. A JSON-nál a megjelenítés sebessége lehet a kérdéses, de erről a megjelenítésről szóló írásomban már esett szó: elég hatékonyan megvalósítható ez is.
Szerver oldalon mind az XML, mind pedig a JSON előállítása elég könnyű lehet: az előbbinek kijelenthetjük, hogy nagy hagyománya van, az utóbbi pedig nagyon egyszerű formátum, s egyrészt ma már szinte minden nyelvre elérhető megfelelő kiegészítés hozzá, másrészt pedig egyszerű
Szalai Ferenc még említi a CSV lehetőségét is, illetve igazából bármilyen szöveges formátum szóba jöhet. Ha nincs valami különösebb oka, hogy így kommunikáljunk, javaslom, ne tegyük: a JSON és az XML jóval hatékonyabb tud lenni, szerver oldalon az előállításban pedig nincsen hatalmas különbség.
A téma iránt érdeklődőknek korábbi írásaim elolvasását mindenképpen javaslom, mivel egyrészt kitértem már ott is a kommunikáció bizonyos vetületeire, másrészt pedig mert a JSON formátum iránt pár projekttel a hátam mögött egy kicsit elfogult vagyok, a hozzászólások között azonban megfelelő és minőségi kritikát kaptam ezügyben. Most ennyit sikerült írni a témáról, remélem, azért sikerült újat is mondanom.
■ A dolog egyébként úgy tűnik, hogy nem csak engem foglalkoztat, hiszen pont egy hasonló írást láthattunk Szalai Ferenc tollából is, én is hasonlókat fogok írni, mint ő.
Lássuk az alapokat: ha a kliens (böngésző) és a szerver (szerver oldali program) kommunikál egymással, mindenképpen kell választanunk valamilyen protokollt, és valamilyen adatformátumot. A protokoll kiválasztása esetünkben egyértelmű, mivel nem nagyon támogat mást a JavaScript és maga a böngésző: ez pedig a HTTP. A kérdés valójában csak az, hogy ezen milyen adatokat küldjünk a kliens felé.
A következő adatformátumok jöhetnek szóba:
- JSON
- XML
- HTML
- JavaScript kód
Mindegyik formátum másra lehet jó, máskor használható, az alkalmazás típusától nagyban függhet, hogy melyik az ideális. Arról, hogy milyen alkalmzástípusok vannak, talán majd még születik egy bejegyzésem, röviden: különválaszthatóak azok, ahol inkább a szerver oldalon, s azok, ahol inkább a kliens oldalon van a logika. A hangsúly persze az inkább szón van, lehet a működés teljesen vegyes is (bár nem feltétlenül célszerű keverni).
Kezdem hátulról - nézzük a JavaScript kód alapú kommunikációt. Ebben az esetben utasítások soráról beszélünk, például a szerver a kliensnek a következő kis programot küldi le:
var message = document.getElementById('message');
content.innerHTML = 'Hello World!';
content.style.display = 'block';
id
-jú elembe belepakol egy szöveget, majd láthatóvá teszi azt a blokkot. Elég összetett programok leküldhetőek a kliensnek, sokmindent megvalósítva. Bár még nem használtam ezt a megoldást, ha minden igaz, akkor a Ruby on Rails-hez elérhető AJAX könyvtár így működik (teljesen tehermentesítve a programozót a JavaScript kódolástól, mindent Ruby-ban lehet leírni, és az generálja a JavaScriptet). Itt kifejezetten arról van szó, hogy a klienst a szerver kézenfogva vezeti, ezt a megoldást főként eseményvezérelt felületek kialakításához tudom elképzelni: a kliens kattint egyet, kitölt valamit, átrendez egy listát, stb., történik egy szerver hívás, majd a visszakapott program például visszajelez (bárhogy), hogy a kért művelet lezajlott. Itt igazából a logika marad a szerver oldalon, a kliens csak a buta végrehajtó szerepet tölti be.A következő lehetőség a HTML formátum. Itt gyakorlatilag arról van szó, hogy a szerver egy oldalrészletet küld a kliensnek, amit az egy az egyben megjelenít (egy adott oldalrészletet lecserélve, kiegészítve). Ilyet használtam a web.zin.hu (és társai) esetén a lapozáshoz - ez egy nagyon egyszerű megoldás, és kiválóan is tud működni. Van neki még egy hatalmas előnye is: segítségével könnyen beilleszthető egy kis AJAX feeling meglévő keretrendszerünkbe, amennyiben az támogatja az oldal egyes részeinek külön "renderelését". Ez a megoldás leginkább lapozás, szűrés, frissítés és ezekhez hasonló tevékenységekhez lehet hasznos, ahol a kliensnek sok dolga nincs. Itt a kliens oldali logika az előző megoldáshoz hasonlóan szintén a nullához közelít. A HTML leküldését szokás AJAH (Asynchronous Javascript and HTML) néven illetni.
Mind a két eddig megoldásra jellemző, hogy inkább a hagyományos weblapok felturbózására, gördülékenyebben történő működtetésére lehet kiváló megoldás, és hogy viszonylag nagyobb sávszélességet igényel. A JavaScript csak egy kiszolgáló, a megjelenítési réteghez tartozó eszköz, még akkor is, ha összetettebb tevékenységeket is végez. Lehet persze okosan elkezdeni turbózni ezeket a megoldásokat, például gyorsítótárazni a kapott HTML-t, és nem kérni le még egyszer, de alapvetően nem fog a helyzet megváltozni. Ha a JavaScriptbe logikát is szeretnénk csepmészni, akkor nem elég kódot vagy HTML-t küldeni neki, mindenképpen valamilyen adatleíró formátumot kell választani. Nos, erre alkalmas az XML és a JSON.
A JSON-ról magáról most nem írnék sokat, aki szeretne, utánanéz majd, hogy pontosan miről van szó. Röviden a lényeg: ez az a formátum, melyben JavaScriptben adatot írhatunk le, így az egyik hatalmas előnye, hogy a JavaScript számára közvetlenül feldolgozható. A közvetlenül feldolgozható azt jelenti, hogy natív változóként jelenik meg az adat, így egy ciklusnak része lehet (iteráció), közvetlenül megcímezhető és lekérdezhető (például
data.settings.size
), továbbá minden más hasonló előnnyel is rendelkezik, ami ezekből adódik.A JSON leküldésnek van egy hátránya, miszerint ha hatékonyak akarunk lenni, a leküldött adathalmazt egy
eval
segítségével "végre kell hajtanunk". Ez egyesek szerint biztonsági kockázat lehet, szerintem viszont a JSON adatot biztonságos forrásból, a saját szerverünkről kell beszerezni (máshonnan elvileg nem is tudja az ember), és akkor már nem. Persze figyeljünk oda, ahogy egy adatbázis beszúrásnál is oda kell figyelni az escape-elésre. Ha nem akarunk hatékonyak lenni, akkor tudjuk validálni a JSON-t egy regexp segítségével, illetve léteznek olyan JS könyvtárak, melyek segítségével "karakterről-karakterre" feldolgozva, eval
nélkül is beszerezhető az adat. A hatékonyság viszont nagyon fontos dolog a böngészőben futó JavaScriptnél.Ahogy írtam, ha a JSON segítségével megvan az adat, elég hatékonyan és gyorsan felhasználható, szinte bármire. Lehet benne a szerver felől parancsokat küldeni, lehet kis adatrészleteket, vagy akár teljes táblázatokat is. Sokan, sokféleképpen használják ezt a formátumot. Előnye minden bizonnyal az, hogy JavaScript műveletekkel könnyen feldolgozható, átalakítható, végrehajtható. Részemről használtam már parancsok átviteli közegeként egy IRC szerver felől, felhasználói beállítások lekérdezésére, tárolására, adatok leküldésére táblázatos adatok megjelenítéséhez, szűréséhez, stb.
A JSON-nak van egy JSONP nevű másik vállfaja, melynek segítségével távoli szerverekről is leszedhetünk adatokat. A trükk az, hogy valójában egy folyton változó JavaScript részletet töltünk le, egy
script
elem dinamikus hozzáadásával az oldalhoz. Na, ez valójában tud veszélyes lenni, a lényeg itt is az, hogy az adatot megbízható forrásból szerezzük be. A delicious, ami kínál ilyen formájú adathozzáférést is, számomra például ilyen.Térjünk át az XML-re. Az XML a böngészőkben futó JavaScript nyelvnek nem kifejezetten natív formátuma, mégis elmondható, hogy manapság már elég sok böngésző alapból támogatja így, vagy úgy, s hogy kialakultak egységes JS API-k a kezelésére. Az XML segítéségével szintén összetett adathalmazokat le tudunk küldeni a kliensnek, s azt kényünkre kedvünkre át is tudjuk alakítani XSLT segítségével, majd megjeleníteni. Az adat JavaScript segítségével is megcímezhető, így bármely részlethez hozzáférhetünk, és JavaScript logikát is vihetünk a dologba.
A JSON és XML formátum között van egy megközelítésbeli különbség. Ha főként megjeleníteni szeretnénk az adatokat különböző szempontok szerint, akkor az XML erre kiválóan alkalmas formátum lehet, hiszen XSLT használatával könnyen és gyorsan alakítható HTML-lé a letöltött adat. Az XML használata ott kezd kevésbé kényelmes lenni, amikor az XSLT beépített függvényei számára nem megoldható adatfeldolgozó logikát szeretnénk a programunkba építeni. Ha nagy mennyiségű adatot szeretnénk JavaScripttel kinyerni az XML-ből, akkor az elég lassú lesz ugyanis - vagy legalábbis nekem nem nagyon sikerült gyorsan megoldani ezt a feladatot. A JSON-nál a megjelenítés sebessége lehet a kérdéses, de erről a megjelenítésről szóló írásomban már esett szó: elég hatékonyan megvalósítható ez is.
Szerver oldalon mind az XML, mind pedig a JSON előállítása elég könnyű lehet: az előbbinek kijelenthetjük, hogy nagy hagyománya van, az utóbbi pedig nagyon egyszerű formátum, s egyrészt ma már szinte minden nyelvre elérhető megfelelő kiegészítés hozzá, másrészt pedig egyszerű
print
/echo
/write
parancsokkal is létrehozható.Szalai Ferenc még említi a CSV lehetőségét is, illetve igazából bármilyen szöveges formátum szóba jöhet. Ha nincs valami különösebb oka, hogy így kommunikáljunk, javaslom, ne tegyük: a JSON és az XML jóval hatékonyabb tud lenni, szerver oldalon az előállításban pedig nincsen hatalmas különbség.
A téma iránt érdeklődőknek korábbi írásaim elolvasását mindenképpen javaslom, mivel egyrészt kitértem már ott is a kommunikáció bizonyos vetületeire, másrészt pedig mert a JSON formátum iránt pár projekttel a hátam mögött egy kicsit elfogult vagyok, a hozzászólások között azonban megfelelő és minőségi kritikát kaptam ezügyben. Most ennyit sikerült írni a témáról, remélem, azért sikerült újat is mondanom.
opera + innerHTML
Az adatokat előre megkaptam egy JSON-s tömbben, azt kellett táblázatba rendezni. A táblázat létrehozása kliens oldalon történt, meg voltak előre a minták, szimpla cserés módszerrel behelyettesítettem az adatokat, majd a sorokat egyenként összemásoltam és behelyettesítettem a
table
elementbe.A problémák Operában kezdődtek, ugyanis eléggé különbözött az eredmény attól, amit vártam. A megoldás az volt, hogy nem a
table
-hoz innerHTML-lezünk, hanem létrehozunk egy div-t amelybe az egész táblázatot rakjuk és atable
elementhez hozzáírjuk astyle="table-layout:fixed"
-t is. Ez nálam megoldotta a problémát.Viszont ha egy sort szeretnék szerkeszteni, akkor ugyanúgy nem jó, igaz csak az adott
tr
elementen bellüli részt rontja el. Ha erre tud valaki megoldást, megkérem, ne tartsa magában.Egyébként jó cikk.
innerHTML
<table>
elemen belülre nem<tr>
-t, hanem például<tbody>
elemeket illik tenni.Ez így félreérthető
Nem azt szeretted volna mondani, hogy a tr elemeket nem közvetlenül a table elemhez kell kapcsolni, hanem tbody/thead-hez és azt table-höz?
De
innerHTML
A hibajelenség az volt, hogy szinte az összes CSS és más formázásra szolgáló kódot figyelmen kívül hagyta és a megjelenített adatok szerkezetileg se nagyon hasonlítottak egy táblázatra, például sokszor össze-vissza csúsztak a cellák. Ezen kívül az események (
onclick
például) szintén nem működtek.Azt tudom, hogy
<tbody>
elemet illik tenni, próbáltam azzal és anélkül is. Az eredmény ugyanaz volt, így bennhagytam, mert mégiscsak illik.Ami a sebességet illeti, nekem korrektnek tűnt. Másrészt így, hogy behelyettesítéses módszert használok, ahelyett, hogy helyben hoznám létre az elementeket, szerintem gyorsabb (bár nem próbáltam ki), ugyanis nagyon sok elemről lenne szó, egyrészt a kódméretet is jelentősen növelné, másrészt az újrafelhasználhatóságot is rontaná -- jelen esetben.
X-JSON header
html szakasz
http://toxin.hu/weblabor/xjson/ajax_fejl_xjson.zip
műkődés lásd firebug alatt, console/post/header fül
teljes példa (ami tartalmazza a különbőző karakterkódolások miatti problémák megoldásását is) a crossForm-ban (kereső),
nagyorsan ennyi, backToMunka :)))
Error: unknown object 'content' in line 2
JSON == objektum/tömb literál
Ez itt kicsit ködösre sikerült. A JavaScriptben lehetőségünk van mondjuk szöveg literálhoz hasonlóan, objektum illetve tömb literál használatára. A JSON az ez.
Felhő
Valóban
for
ciklusban feldolgozhatjuk, a beépített tömbkezelő utasításokkal műveleteket hajthatunk végre rajta, stb. Ez magától adódik persze, ha valaki tudja, hogy mi az a JSON.ez is használható