Flash szerkesztési és grafikai alapok
 
Általános információk
Tanfolyamok ismertetése
Regisztráció
Belépés a rendszerbe
Bemutató fejezet.

 

AJAX bevezető

A webre fejlesztők közös nyelve a HTML, ennek segítségével tudják megfogalmazni gondolataikat. Sajnos a HTML nagyon korlátozott lehetőséget nyújt a felhasználói interakcióra, konkrétan hivatkozások, gombok és űrlapok formájában. Sok fajta technológiai megoldás született ennek kiküszöbölésére, a felhasználói élmény fokozására a böngészőn belül. Ilyenek a Java Applet-ek, a Flash mozik, és az ActiveX kontrollok is.

Mindegyiknek megvan a saját előnye és hátránya. Itt most két legfontosabb hátrányt a platform függőséget és a "lejátszó" plug-in telepítésének szükségességét emelhetjük ki.

Nemrégiben elindult egy új, izgalmas irányvonal, ami ezen hátrányokat jól kiküszöböli. Ezt az új technológiát AJAX-nak keresztelték el. A betűszó az "Asynchronous JavaScript and XML" rövidítése, azaz aszinkron JavaScript és XML. Nézzük meg pontosan, hogy mit is jelent ez. Az aszinkron egy olyan dolog, amivel eddig a web programozóknak nem kellett törődnie, azaz, hogy kérés a háttérben fut. A JavaScript mindenkinek ismerős kell, hogy legyen, ebben a kontextusban azt jelenti, hogy az Ajax "programozási nyelve" a JavaScript. A szemfüles programozó arra is rájön belőle, hogy ez egy böngésző oldali technológia. Az XML pedig az "eXtended Markup Language", egy mostanában futótűzként terjedő technológia, amivel egyszerűen, több rendszer között is viszonylag könnyen értelmezhető, szabványos módú kommunikációs üzenet forma valósítható meg.

Szóval mi is az az AJAX, ezt még mindig nem értjük! Az AJAX egyszerűen egy új funkció a böngészőkben, amely segítségével a háttérben kérés küldhető a szerver felé. Mindezt anélkül, hogy frissítenénk az oldalt vagy elnavigálnánk onnan. A kérésre kapott választ JavaScript-ből feldolgozhatjuk és az oldal egyes részeit frissíthetjük.

A webes világ az AJAX-ot mégis egy kicsit szélesebben értelmezi, többnyire beleértik a hozzá szorosan és néha kevésbé szorosan kapcsolódó egyéb JavaScript megoldásokat is.

Ennek a fejezetnek rövid bevezetőt nyújt, hogyan valósítható meg a szigorúbb értelemben vett AJAX a modern böngészőkben. Először bemutatunk néhány frame-ekre épülő megoldást, majd egy egyszerűbb utat világítunk meg az XMLHttp segítségével.

A fejezetben elkészített példákat letöltheti külön-külön az alfejezetek elején található hivatkozásra kattintva, vagy egy csomagolt fájlban.

[ Demo oldal ]

AJAX-hoz vezető megoldások. Miért jobb az AJAX?

Gyakran előfordul, hogy a fejlesztés során a kliens oldali és a szerver oldali feladatok külön válnak, és más személy, vagy csapat kezébe kerül a két terület. Az is megfigyelhető azonban, hogy a szerver oldali programozóknak gyakran részben, vagy egészében a kliens oldali technológiákat is el kell sajátítaniuk, míg egy nagyszerű kliens oldali programozó nem feltétlenül ismeri mélységeiben a szerver oldali lehetőségeket.

Az Ajax megjelenésével ez szükségszerűen megváltozik, és azoknak a kliens oldali fejlesztőknek, akik használni szeretnék az új technológiát, meg kell ismerniük a másik oldalt.

Ajax kommunikációs technikák

Azt tudjuk, hogy a böngésző és a kiszolgáló közötti párbeszéd a HTTP segítségével valósul meg, melynek során kérések és válaszok tömkelege vándorol a weben. Alapesetben egy kérés csak akkor generálódik, amikor a felhasználó valamely módon ezt kiváltja. Az Ajax használatával nem kell várni a felhasználóra, a szerverrel bármikor kezdeményezhetünk párbeszédet.

A rejtett (hidden) Frame technika

Az alapötlet az, hogy egy olyan frameset-et készítünk, amelynek egyik tagjának szélessége és magassága is egyaránt 0 pixel, ebből következően nem látszik, és kizárólag a szerverrel történő kommunikációra használjuk.

A kommunikáció minden esetben a 2.1 ábrán látható 4 lépéses minta alapján zajlik. Az első lépés a látható keretben történik, ahol a felhasználó, mit sem sejtve arról, hogy létezik a másik frame, a szokásos módon használja az oldalt, és olyan műveletet kezdeményez, aminek a kiszolgálásához további adatokra van szükség a szerverről.

Ebben a pillanatban egy JavaScript hívás történik a rejtett frame-re. Ez a hívás lehet egy egyszerű átirányítás, de akár egy űrlap adatainak elküldése is, a lényeg, hogy bekövetkezik a folyamat második lépése, egy HTTP kérés.

A harmadik lépés a szervertől kapott válasz fogadása. Mivel frame szerkezetben dolgozunk, a válasz nyilván egy újabb weboldal lesz, ami tartalmazza a szervertől kért adatokat, és azt a JavaScript kódot, ami átadja azokat a látható frame-nek.

Végül, a negyedik lépésben az előbb említett JavaScript kód lefut. Tipikusan ez úgy történik, hogy a visszaküldött oldal onload eseménykezelőjében hívunk meg egy függvényt a látható frame-ben, és átpasszoljuk a megkapott adatokat, amelyek sorsáról már a látható frame feladata lesz gondoskodni.

A rejtett frame technika alapelve

Rejtett frame GET típusú kéréssel

Kipróbálom Letöltöm

A legjobb módszer a példán keresztüli tanulás, ezért most is ezt alkalmazzuk. Mivel ez az első példa, nagyon egyszerű lesz.  A feladat az, hogy egy ügyfél adatbázisból az ügyfél azonosító (ID) megadása után visszakapjuk a hozzá tartozó adatokat. Feltételezzük, hogy az adatok SQL adatbázisban vannak, ezért szükségünk lesz szerver oladli programozásra is. Ehhez a példában PHP-MySQL-t használunk.

A példában MySQL-t használunk, de nagy valószínűséggel minimális módosítással, vagy anélkül, működni fog más adatbázisokkal is.

A példa használatához létre kell hozni egy tetszőleges adatbázist, és abban egy táblát. A következő SQL paranccsal hozhatjuk létre a táblát.

create table customer (
	customer_id int(11) not null auto_increment,
	name varchar (255) not null default '',
	address varchar (255) not null default '',
	city varchar (255) not null default '',
	zip varchar (255) not null default '',
	phone varchar (255) not null default '',
	email varchar (255) not null default '',
	primary key (customer_id)
) type=myisam comment='ugyfel adatok'; 
A kódokban és az adatbázis táblákban angol elnevezéseket fogunk használni, mivel jobban beleillik a MySql és a PHP amúgy is angol környezetébe. A példák felhasználó által látható felületei természetesen magyar nyelven fognak elkészülni.

Az adatbázist és a táblát létrehozó, és adatokkal feltöltő script benne van a fejezethez tartozó letölthető források között.

Miután az adatbázis és a tábla elkészült, és ellenőriztük, jöhet a HTML rész. Mivel ugye a "hidden frame" technikát használjuk, a létrehozandó frameset valahogy így fog kinézni:

index.html

<frameset rows="100%, 0" frameborder="0">
	<frame name="displayFrame" src="display.htm" noresize="noresize" />
	<frame name="hiddenFrame" src="about:blank" noresize="noresize" />
</frameset>

Ebből azonnal látszik, hogy olyan frameset-et hozunk létre, amelynek második sora 0 magasságú, azaz nem látszik, de nevet természetesen kell neki adni, hiszen itt zajlanak majd a háttér események, tehát hivatkoznunk kell majd rá. Ennél a technikánál a frame-ek méretezését célszerű letiltani.

Következzék a felhasználó által használt oldal, ahol elkérjük a felhasználó azonosítóját, és a többi adatot is itt fogjuk majd megjeleníteni:

display.html

function requestCustomerInfo() {
	var sId = document.getElementById("txtCustomerId").value;
	top.frames["hiddenFrame"].location = "getcustomerdata.php?id=" + sId;
}

<p>Add meg a keresett ügyfél azonosítóját:</p>
<p>Azonosító: <input type="text" id="txtCustomerId" value="" /></p>
<p><input type="button" value="Ügyfél adatai" 
	onclick="requestCustomerInfo()" /></p>

<div id="divCustomerInfo"></div>

Ez egy elég egyszerű oldal, amin csak egy input box van, amibe bekérjükmajd az azonosítót, ennek elküldésére egy gomb, és egy <div/> elem, ahová a visszakapott adatokat majd elhelyezzük. A gomb megnyomásakor a vezérlés a requestCustomerInfo() nevű JavaScript  függvényre ugrik, ami a rejtett frame-et átirányítja a getcustomerdata.php oldalra, és a query sztringben átadja neki a beírt ügyfél azonostót.

Érdemes tanulmányozni a rejtett frame-re történő hivatkozást. A top objektummal a böngésző legfelső szintű ablakát érjük el. Ennek van egy frames tömbje, aminek egyik eleme a "hiddenFrame" nevű. Mivel minden frame egy újabb window objektum, annak a location tulajdonságát egy adott URL-re állítva, meg is történik az oldal lekérése.

Ahogy átadtuk a beírt azonosítót a rejtett frame-nek , úgy a megkapott további adatokat vissza is kell juttatni a felhasználó által látott frame-be. Ehhez nyilván egy újabb JavaScript függvényre lesz szükség, amit a rejtett frame hív meg, miután a PHP visszaadta a kért adatokat. A függvény paramétere, az ügyfél megjelenítendő adatait tartalmazó sztring lesz.

function displayCustomerInfo(sText) {
	var divCustomerInfo = document.getElementById("divCustomerInfo");
	divCustomerInfo.innerHTML = stext;
}

Ezt a függvényt még adjuk hozzá az előző, display.html oldalhoz, és ezzel ennek kódolása be is fejeződött. Ideje megnézni a szerver oldali feladatokat.

A getcustomerdata.php egy alap HTML oldal, két PHP blokkal. Az első blokk a query stringben átvett azonosító alapján lekérdezi az adatbázisból az ügyfél többi adatát, és elhelyezi azt egy változóban. Ezt a blokkot később külön tárgyaljuk. A második blokk az említett változó tartalmát egy<div/> elembe helyezi.

getcustomerdata.php

<html>
<head>
<title>Ügyfél adatainak lekérése</title>
<?php

// PHP kód, ami lekéri az ügyfél adatait az adatbázisból

?>
</head>
<body>

<div id="divInfoToReturn"><?php echo $sInfo ?></div>

</body>
</html>

Tehát ez az oldal töltődik a rejtett frame-be, magába foglalva a szervertől kapott választ. Ezután nincs más hátra, mint az oldal betöltődése után egy JavaScript függvénnyel a</div> tartalmát át kell küldeni a megjelenítő frame-be:

window.onload = function () {
    var = document.getElementById("divInfoToReturn");
    top.frames["displayFrame"].displayCustomerInfo(divInfoToReturn.innerHTML);
};

Az első sorban lekérjük a</div> hivatkozását, a második sorban a megjelenítő frame-ben korábban definiált displayCustomerInfo() függvényt hívjuk, átadva neki a </div> innerHTML tulajdonságát, azaz a tartalmát.

Ideje rátérni az első PHP blokk részleteire, amelyben kiderül, hogy az ügyfél azonosítójából hogyan is áll elő a $sInfo változó tartalma. Először szükségünk lesz az adatbázis elérési adataira, majd ha sikeresen csatlakoztunk, lefuttatjuk a szükséges lekérdezést.

Idézzük fel, hogyan is hívtuk meg ezt az oldalt? A rejtett frame-et átirányítottuk a következő URL-re: getcustomerdata.php?id=" + sId. A PHP blokk elején az url-ben kapott változót hozzuk étre a szokásos $_GET tömb segítségével, majd a $sInfo szrtingváltozót is inicilizáljuk, üres tartalommal.

A példa kipróbálásához, az adatbázis eléréséhez szükséges változókba a saját fejlesztőkörnyezetben használt adatokat adjuk meg!

<?php
$sID = mysql_escape_string($_GET['id']);
$sInfo = '';

$sDBServer = 'your.database.server';
$sDBName = 'your_db_name';
$sDBUsername = 'your_db_username';
$sDBPassword = 'your_db_password';

$sQuery = '
	select * 
	  from customer 
	 where customer_id=' . $sID;
	 

$oLink = mysql_connect($sDBServer, $sDBUsername,$sDBPassword);
@mysql_select_db($sDBName) or $sInfo = 'Unable to open database';

if($oResult = mysql_query($sQuery) and mysql_num_rows($oResult) > 0) {
	$aValues = mysql_fetch_array($oResult,MYSQL_ASSOC);
	$sInfo = 
		$aValues['name'] . '<br/>' .
		$aValues['address'] . '<br/>' .
		$aValues['city'] . '<br/>' . 
		$aValues['state'] . '<br /><br/>Telefonszám: ' .
		$aValues['phone'] . '<br/>' .
		'<a href=\'mailto:' . $aValues['email'].'\'>' .
		$aValues['email'] . '</a>'
	;
} else {
	$sInfo = 'Nem létező ügyfél azonosító:' . $sID;
}

mysql_close($oLink);

?>

Ha találtunk a megadott azonosítóhoz tartozó rekordot, akkor a $sInfo változóba HTML formátumban, sortörésekkel elválasztva összefűzzük a mezők tartalmát. Sikertelen kapcsolódás, vagy nem megfelelő azonosító esetén pedig hibaüzenetet küldünk vissza.

Rejtett frame POST típusú kéréssel

Kipróbálom Letöltöm

Általánosságban elmondható, hogy a GET-et inkább adatok lekérésére, míg a POST-ot inkább adatok küldésére használjuk. Ennek több oka is lehet, de tekintsük a legegyértelműbbet, mégpedig azt, hogy a query sztringgel küldött adatok mennyisége (512 KB) sokkal kisebb lehet, mint a POST-olt adatoké (2 GB)

Ugye emlékszünk még arra, amikor a hőskorban a POST kéréseket csak az űrlapok elküldéséhez használtuk amethod tulajdonság post-ra állításával? Ezzel most az a probléma, hogy az űrlap elküldésekor a böngésző az action tulajdonságban megadott oldalra navigál, azaz egy új, teljes oldalt tölt le, ami teljesen ellentétes az Ajax céljaival.

Szerencsénkre azonban létezik az űrlapoknak egy kevésbé ismert, target nevű attribútuma. Ha ezt beállítjuk, akkor a kitöltött űrlapot tartalmazó oldal megmarad, és az action által meghatározott cél oldal a target szerint egy új ablakba, vagy egy frame-be töltődik. Miért ne lehetne ez akár egy rejtett frame?

Készítsünk egy új oldalt az előző példa szerinti frameset-tel. A különbség csak az, hogy a látható frame-be másik HTML fájlt töltünk. (entry.html)

<frameset rows="100%,0" frameborder="0">
	<frame name="displayFrame" src="entry.html" noresize="noresize" /> 
	<frame name="hiddenFrame" src="about:blank" noresize="noresize" /> 
</frameset>

A feladatunk az lesz, hogy új ügyfelet tudjunk felvenni az adatbázisba.. Ehhez készítünk egy űrlapot, ahol az adatokat lehet majd felvinni. Az ügyfél azonosító nem lesz itt, mert azt az adattáblában automatikusként definiáltuk. Az űrlap után hozzuk létre azt a divStatus nevű <div/> elemet, amit a szerverről érkező üzenetek megjelenítéséhez használunk.

entry.html

<form method="post" action="savecustomer.php" target="hiddenFrame">

	<p>Ajda meg az elmentendő ügyfél adatokat:</p>
	
	<p>
	Ügyfél neve: <input type="text" name="txtName" value="" /><br />
	Cím: <input type="text" name="txtAddress" value="" /><br />
	Város: <input type="text" name="txtCity" value="" /> <br />
	Irányítószám: <input type="text" name="txtZipCode" value="" /><br />
	Telefonszám: <input type="text" name="txtPhone" value="" /> <br />
	E-mail: <input type="text" name="txtEmail" value="" /> 
	</p>
	
	<p><input type="submit" value="Ügyfél adatok mentése" /> </p>

</form>

<div id="divStatus"></div>

Az első sorban látható, hogy a <form/> elem target tulajdonságát beállítottuk, ezért ha a felhasználó elküldi az űrlapot, a kérés a rejtett frame-be kerül.

A megjelenítő oldalra már csak egy JavaScript függvény szükséges, amit akkor hívunk meg, amikor a rejtett frame visszaadja a szerver válaszát.

function saveResult(sMessage) {
	var divStatus = document.getElementById("divStatus");
	divStatus.innerHTML = "Kérés végrehajtva: " + sMessage;
}

Most akkor nézzük meg a szerveroldali teendőket. Az előző, példához hasonlóan most is egy egyszerű HTML oldalról van szó, egy kevés PHP és JavaScript kóddal fűszerezve.

<?php
	$sName = mysql_escape_string($_POST['txtName']);
	$sAddress = mysql_escape_string($_POST['txtAddress']);
	$sCity = mysql_escape_string($_POST['txtCity']);
	$sZipCode = mysql_escape_string($_POST['txtZipCode']);
	$sPhone = mysql_escape_string($_POST['txtPhone']);
	$sEmail = mysql_escape_string($_POST['txtEmail']);
	
	$sStatus = '';

	$sDBServer = 'your.database.server';
	$sDBName = 'your_db_name';
	$sDBUsername = 'your_db_username';
	$sDBPassword = 'your_db_password';
	
	$sSQL = "
		insert 
		  into customers 
		       (name, address, city, state, zip, phone, email) 
		values (
		        '$sName', '$sAddress', '$sCity', '$sState', 
		        '$sZipCode', '$sPhone', '$sEmail'
		       )
	";
		
	$oLink = mysql_connect($sDBServer,$sDBUsername, $sDBPassword);
	
	@mysql_select_db($sDBName) or $sStatus = 'Unable to open database';
	
	if($oResult = mysql_query($sSQL)) {
		$sStatus = 
			'Ügyfél sikeresen rögzítve; Ügyfél azonosító ' . 
			mysql_insert_id();
	} else {
		$sStatus = 'Hiba történt az ügyfél rögzítése közben. ' . 
		'Adatok mentése sikertelen!';
	}
	
	mysql_close($oLink);

?>

A PHP a POST metódussal küldött adatokat a $_POST tömb segítségével begyűjti, és tárolja az adatbázisban. A megjelenítő oldal számára pedig, a $sStatus valtozó tartalmát kell valahogy visszajuttatni. Ehhez ismét azonload eseményt használjuk fel.

window.onload = function () {
	top.frames["displayFrame"].saveResult("<?php echo $sStatus ?>");
}

A PHP oldal teljes betöltődésekor tehát a megjelenítő frame-ben definiált Saveresult függvényt hívjuk, és a PHP által korábban már kitöltött$Status változót adjuk át paraméterként. Mivel ez egy sztringváltozó, a PHP echo parancsát idézőjelek közé kellett tenni.

Kész is vagyunk. Kipróbáláskor látható az Ajax előnye: az oldal újratöltése nélkül, ugyanazzal az űrlappal, egymás után több ügyfelet is felvehetek az adatbázisba.

Rejtett iFrame

A HTML 4.0-val érkező iframe-mel új lehetőség nyílt a háttérben történő kliens-szerver kommunikációra. Egy  iframe tulajdonképpen ugyanaz, mint egy hagyományos frame, azzal a különbséggel, hogy az oldal bármely területén elhelyezhető, nincs szükség frameset definiálására. Ebből következően JavaScript segítségével akár futásidőben, dinamikusan is elő lehet állítani. Mindez Ajax funkciókkal kibővítve, kiváló lehetőségekkel kecsegtette a fejlesztőket.

Get kérés beágyazott iFrame elemmel

Kipróbálom Letöltöm

Ebben az esetben viszonylag egyszerű dolgunk lesz. Csak beágyazunk egy rejtett <iframe/> elemet az oldalba, majd ezután az első példában látott módon tudunk kéréseket indítani a szerver felé. Ehhez a megjelenítő oldal kódját át kell alakítani:

<p>Add meg a keresett ügyfél azonosítóját:</p>

<p>Azonosító: <input type="text" id="txtCustomerId" value="" /></p>

<p><input type="button" value="Ügyfél adatai" 
	onclick="requestCustomerInfo()" /></p>

<div id="divCustomerInfo"></div>

 

<iframe 
	src="about:blank" name="hiddenFrame" width="0" 
	height="0" frameborder="0"></iframe>

Az iframe width, height és frameborder tulajdonságai egyaránt 0 értékre vannak állítva, emiatt marad rejtve. Mivel a neve továbbra is hiddenFrame,  minden JavaScript kód továbbra is működni fog.

Viszont a getcustomerdata.php oldal JavaScript kódját kis mértékben változtatni kell. Az eredeti verzió a displayframe nevű frame-ben keresett egy displayCustomerInfo() fügvényt. Mivel most nincs ilyen nevű frame-ünk,  a parent hivatkozást kell használnunk.

window.onload = function () {
	var divInfoToReturn = document.getElementById("divInfoToReturn");
	parent.displayCustomerInfo(divInfoToReturn.innerHTML);
};

Get kérés dinamikus iFrame elemmel

Kipróbálom Letöltöm

Amikor dinamikusan hozunk létre egy iframe-et, kicsit trükközni kell, mert a különböző böngészők eltérő módokon valósítják meg az iframe-eket.

var oIFrame = null;
function createIFrame() {
	var oIFrameElement = document.createElement("iframe");
	
	oIFrameElement.width=0;
	oIFrameElement.height=0;
	oIFrameElement.frameBorder=0;
	oIFrameElement.name = "hiddenFrame";
	oIFrameElement.id = "hiddenFrame";
	
	document.body.appendChild(oIFrameElement);
	
	oIFrame = frames["hiddenFrame"];
}

Az iframe-et a document.createElement() metódussal hozzuk létre, és ezután hozzárendeljük a szükséges attribútumokat. A name és az id egyaránt meg van adva, mert némely böngészők az iframe-eket name, mások pedig id alapján azonosítják. Nagyon fontos az a sor, ahol az appendChild() metódussal az új iframe-et hozzáadjuk a dokumentum struktúrához. E nélkül nem tudna a szerver felé kéréseket indítani. Az oIFrame globális változóban tároljuk az iframe objektum hivakozását.

Végül módosítjuk a requestCustomerInfo() függvényt is.


function requestCustomerInfo() {
	if (!oIFrame) {
		createIFrame();
		setTimeout(requestCustomerInfo, 10);
		return;
	}
	
	var sId = document.getElementById("txtCustomerId").value;
	oIFrame.location = "GetCustomerData.php?id=" + sId;
}

A függvény megvizsgálja, hogy létezik-e már az iframe. ha az oIFrame globális változónk még nincs értéke, akkor meghívja a createIFrame() függvényt, majd 10 msec. múlva újrahívja saját magát. erre azért van szükség, mert az IE az egyedüli böngésző, amely azonnal érzékeli az új iframe-eket, a többi böngészőnek ez egy kis időbe telik. Miután másodszorra is lefut, az új iframe már biztosan látható, és a kód többi része is végrehajtódik.

POST kérés dinamikus iFrame elemmel

A GET típusú kérések esetén, ahogy láttuk, viszonylag egyszerű dolgunk van. A POST története azonban teljesen más, ugyanis kevés böngésző engedi meg azt, hogy egy űrlap target tulajdonságát egy dinamikusan előállított iframe elemre állítsuk. Többek között az IE sem enged ilyesmit, úgyhogy megint jöhet a trükközés. A megoldás az lesz, hogy a kitöltött űrlap adatait az elküldés után valahogy átirányítjuk a rejtett iframe-be, és onnan POST-oljuk tovább a szervernek.

Összegzés

Az itt leírt technikák évek óta ismertek és használatban vannak sok Ajax alkalmazásban. Létezik még néhány szempont, amit érdemes figyelembe venni, mielőtt kiválasztjuk a megfelelő technikát.

Az itt ismertetett példáknál a funkcionalitás bemutatására törekedtünk, emiatt a lehető legegyszerűbb kódokat mutattuk be. Valós helyzetben nyilván ennél összetettebb a feladat, például a válasz megérkezéséig célszerű a felhasználó által használt űrlapot letiltani.

Böngésző History kezelése

Ha rejtett frame-eket használunk, a history működése zavartalan marad, a felhasználó továbbra is tudja használni a "Vissza" és "Előre" gombokat. Ennek az az oka, hogy a böngésző nem tudja, hogy egy frame valójában rejtett, és egyformán kezeli a látható párjával, azaz továbbra is tárolja azokat a kéréseket, amelyek rajta keresztül indultak.

A rejtett iFrame esetén már más a helyzet, a böngészők jelenleg ezt eltérően kezelik. Az IE minden iframe esetén tárolja a history-t, a FireFox csak a statikus iframe-ek esetén,  és pl. a Safari egyik esetben sem.

Árnyoldal

A rejtett frame-ekkel kapcsolatban az lehet a probléma, hogy elég kevés információnk van arról, ami a háttérben történik. Valójában csak bízni tudunk abban, hogy a kért adat visszaérkezik a szervertől. Mi van, ha bármi miatt nem sikerül a szerverrel kommunikálni? A fő oldal továbbra is működik, semmi jele, hogy probléma lenne, csak várunk a megfelelő JavaScript függvény hívására. A fejezetben bemutatott példák mindegyike szenved ebben a betegségben. Be lehetne esetleg állítani egy timeout-ot, aminek letelése után adunk némi információt, de ez a megoldás nem az igazi.

Szerencsénkre van még egy lehetőségünk: az XMLHttp

XMLHttp

Kipróbálom Letöltöm

Az XMLHTTP egy Microsoft találmány, amelyet később, többé-kevésbé hasonlóan, a többi böngészőbe is megvalósítottak. Sajnos a web világában már megszokhattuk, hogy nem elég egyszer megírni a kódot és azt egyszer letesztelni, hanem ezeket a lépéseket több különböző böngészőn is el kell végeznünk. Sőt, gyakori az is,  hogy ugyan azt a kódot többféleképpen kell megírnunk függően attól, hogy milyen böngészőt detektálunk. Ugyan ez a helyzet az XMLHTTP objektummal is. Első lépésként hozzunk létre egy ilyen objektumot Internet Explorerben. A Microsoft ezt a lehetőséget egy ActiveX komponensen keresztül biztosítja, aminek neve Microsoft.XMLHttp. Létrehozása viszonylag egyszerű:

var request = new ActiveXObject(´Microsoft.XMLHTTP´);

Ez a kód sajnos kizárólag Internet Explorerben működik. A Mozilla fejlesztői úgy gondolták, hogy a Microsoft egy jól használható objektumot hozott létre, ezért megalkották saját osztályukat erre a feladatra, amit XMLHttpRequest névre kereszteltek. Ennek létrehozása még egyszerűbb, mint az előző esetben:

var request = new XMLHttpRequest();

Vegyítsük a kettő megoldást egy "böngésző független" megoldássá. Ehhez meg kell vizsgálni, hogy létezik-e XMLHttpRequest osztály, illetve, hogy létezik-e ActiveXObject. Ha valamelyik létezik, akkor az annak megfelelő objektumot hozzuk létre:

function createXmlHttp() {
    var request = null;
    if (window.XMLHttpRequest) {
         request = new XMLHttpRequest();
    }
    else if (typeof ActiveXObject != undefined) {
         request = 
               new ActiveXObject('Microsoft.XMLHTTP');
    }
    return request;
}

Figyeljünk a kis és nagy betűk közötti különbségre, mivel a javascript érzékenyen reagál erre. Ha készen van az objektum, akkor küldjünk el vele egy kérést a szervernek. Ehhez először elkészítünk egy XMLHTTP objektumot, ha ez sikerült, akkor az open() metódussal megnyitunk egy GET típusú kérést, majd elküldjük a megfelelő paraméterekkel a szervernek.

function requestCustomerInfo() {
    var sId = 
         document.getElementById("txtCustomerId").value;

    var ajaxRequest = createXmlHttp();
    if (ajaxRequest) {
         ajaxRequest.open(
               'get', 
               'getcustomerdata.php?id=' + sId, true);
         ajaxRequest.send();
    }
}

Egy lényeges dolog hiányzik: a szerver által visszaadott adatok feldolgozása. Ehhez írnunk kell egy esemény feldolgozó függvényt, vagy más néven "callback" függvényt, amely akkor hívódik meg, ha a kérés állapotában változás áll be. Minket jelenleg csak egy változás érdekel, amikor visszakapjuk a kérés eredményét, tehát az egész folyamat lezárult. A függvénynek szüksége van a kérésre, hogy eldönthesse: megvan-e a válasz a szervertől. Erre készítsünk egy globális változót, amiben a kérésünket tárolni fogjuk.

var ajaxRequest = null;
function requestCustomerInfo() {
    var sId = 
         document.getElementById("txtCustomerId").value;

    ajaxRequest = createXmlHttp();
    if (ajaxRequest) {
         ajaxRequest.open(
               'get', 'getcustomerdata.php?id=' + sId, true);
         ajaxRequest.send();

    }
}

A függvényünkben, amelyik a változáskor hívódik meg, le kell kezelni a különböző állapotokat. Azt hogy éppen milyen fázisban van a kérés azt az objektum readyState tulajdonságában találjuk meg. Ennek értéke 4, ha a kérés befejeződött és az adatokat visszakaptuk a szervertől. Tehát először ellenőrizzük le, hogy megfelelő-e a státusz. Ha nem, akkor ne is haladjunk tovább:

function ajaxCustomerInfo() {
    if (ajaxRequest.readyState != 4) {
         return;
    }
}

A kérés végén az objektum responseText tulajdonságában érhetjük el a szerver válaszát. Ezt helyezzük el a megfelelő <div/> elembe:

    var divCustomerInfo = 
         document.getElementById('divCustomerInfo')
    divCustomerInfo.innerHTML = 
         ajaxRequest.responseText;

Már csak egy feladatunk maradt, be kell állítani, hogy a mi függvényünk hívódjon meg, amikor változás áll be a kérés állapotában. Mielőtt a send() metódussal elküldjük a kérést, állítsuk az onreadystatechange tulajdonságot a saját függvényünkre:

         ajaxRequest.onreadystatechange = 
               ajaxCustomerInfo;

Ahhoz, hogy működjön a getcustomerdata.php átírása nem feltétlenül szükséges, de érdemes. Ugyanis eddig szükség volt arra, hogy szerver teljes HTML kódot adjon vissza, mivel azt egy frame-be töltöttük be. XMLHTTP kérés esetén ezek csak fölösleges szövegek, elég a ténylegesen kiírandó információ tartalmat visszaadni:

<?php

$sID = mysql_escape_string($_GET['id']);

//itt minden ugyan az mint az előző esetben ...

mysql_close($oLink);

echo $sInfo;

?>

A gyakorlott programozó már nem lepődik meg, amikor kipróbálja az eddig összeállított példát, és kérdőjeleket lát a visszakapott szöveg ékezeteinek helyén. Ennek oka, hogy a böngésző rosszul értelmezi a visszakapott választ. Egyszerűen javíthatjuk a hibát, ha megmondjuk, hogy milyen kódlappal kell értelmezni a választ:

<?php

header('Content-Type: text/html; charset=iso-8859-2');

...

Amennyiben az adatbázis létrehozásánál már kódlappal dolgoztunk, akkor  konvertálás helyett érdemes azt megadni.

Összegzés

Reméljük sikerült mindenkit meggyőzni, hogy az XMLHTTP kezelése pofon egyszerű feladat. Milyen előnyök járnak az előzőekben leírt hidden frame-s technikával szemben? Egyrészt sokkal áttekinthetőbb javascript kódot eredményez, mivel minden függvény egy fájlban maradhat. A szerver oldalon pedig nem kell a megjelenítéssel foglalkozni, csak az adatok összegyűjtésével, így ez a kód is átláthatóbb marad.

Hasznos linkek




A Pentaschool Oktatási Központ bármely dokumentumának vagy dokumentum
részletének másolása kizárólag a tulajdonos írásos engedélyével történhet!

Copyright 2002-2003 Pentaschool Bt.
Minden jog fenntartva.

       
 
Címünk: 1051 Budapest, Sas utca 25. VI. em. Telefon/Fax: (1) 472-0679 E-mail nekünk Médiaajánlat