Přidat článek mezi oblíbenéZasílat nové komentáře e-mailem Ajax - XMLHttpRequest

V predchádzajúcom dieli bolo vymenovaných niekoľko možných spôsobov komunikácie medzi klientom a serverom. Dnes sa zameriame na jeden z nich a ukážeme si, ako odosielať požiadavky a spracovať odpovede prostredníctvom objektu XMLHttpRequest.

Spôsobov, ako implementovať komunikáciu klienta so serverom je viac, avšak použitie objektu XMLHttpRequest sa s technikou Ajax spája asi najčastejšie. Použitie tohto objektu je v podstate jediné čisté riešenie komunikácie, pri ktorom sa technológia používa presne na to, na čo bola určená. XMLHttpRequest umožňuje vytvárať požiadavky s použitím rôznych metód, vrátane metód GET a POST. V dnešnej dobe ho podporujú všetky súčasné prehliadače.

Objekt XMLHttpRequest umožňuje prenášať údaje vo formáte XML, vďaka čomu môžeme na strane klienta jednoduchšie spracovávať prijaté údaje. Rovnako je však možné prenášať čistý text, čo sa hodí v prípadoch, v ktorých by bol XML formát kanónom na vrabce. Hoci je XMLHttpRequest určený na komunikáciu klienta so serverom, nie vždy je to tá najlepšia voľba. Nedostatkom objektu XMLHttpRequest je, že v prehliadači Internet Explorer je možné tento objekt vytvoriť iba s použitím technológie ActiveX. To môže byť problémom, pretože pri vyššom stupni zabezpečenia sa pri vytváraní tohto objektu môže používateľovi zobraziť otravná hláška, prípadne sa nemusí objekt XMLHttpRequest vôbec vytvoriť. V prehliadači Internet Explorer 7 už toto obmedzenie neplatí a objekt XMLHttpRequest sa dá vytvoriť rovnakým spôsobom ako v ostatných prehliadačoch.

Ďalšou vlastnosťou komunikácie prostredníctvom objektu XMLHttpRequest je, že nie je možné komunikovať so serverom z inej domény, než z ktorej bol spustený skript. Toto obmedzenie sa dá obísť nastavením prehliadača, ale z bezpečnostného hľadiska to nie je príliš rozumné. Ak by totiž bola povolená komunikácia so servermi z inej domény, bolo by jednoduché okrem iného napríklad hlasovať za nejakú možnosť v ľubovoľnej ankete, prípadne z Vašej IP adresy vložiť príspevok do nejakej diskusie na inej stránke. Pre komunikáciu so servermi z inej domény je preto lepšie vytvoriť na serveri proxy stránku, ktorá takúto komunikáciu zabezpečí.

Vytvorenie objektu XMLHttpRequest

Pri vytváraní objektu XMLHttpRequest sa postupne skúšajú viaceré spôsoby. Uprednostňuje sa vytvorenie objektu XMLHttpRequest jeho konštruktorom, ako keby to bol objekt ako každý iný. Až v prípade, že konštruktor nie je k dispozícii, príde na rad vytvorenie tohto objektu pomocou technológie ActiveX. V mnohých ukážkach na webe bolo toto poradie opačné a v podstate na ňom do istej doby ani nezáležalo. Ak bola k dispozícii technológia ActiveX, vytvoril sa XMLHttpRequest pomocou nej a až keď sa to nepodarilo, použil sa konštruktor pre XMLHttpRequest. Príchodom prehliadača Internet Explorer 7 už na poradí záleží, pretože ten umožňuje vytvoriť XMLHttpRequest obidvomi spôsobmi, pričom chceme uprednostniť natívny objekt XMLHttpRequest.

function createXhr ()
{
	var xhr = null;

	if (window.XMLHttpRequest)
		xhr = new XMLHttpRequest ();
	else if (window.ActiveXObject)
		try { xhr = new ActiveXObject ("Msxml2.XMLHTTP"); }
		catch (e)
		{
			try { xhr = new ActiveXObject ("Microsoft.XMLHTTP"); }
			catch (e) {}
		}

	return xhr;
}

Možno sa pýtate, prečo sa pokúšame vytvoriť ActiveX objekt Msxml2.XMLHTTP a pri neúspechu vyskúšame ActiveX objekt Microsoft.XMLHTTP. Je to tým, že objekt XMLHttpRequest má viacero implementácií. Pomocou objektu Microsoft.XMLHTTP bolo možné vytvoriť objekt na komunikáciu so serverom dávno pred tým, než sa objavil objekt XMLHttpRequest v iných prehliadačoch. Neskôr vznikla ďalšia verzia tohto objektu Msxml2.XMLHTTP, ktorá sa líši snáď iba pomenovaním.

Vytvorený objekt XMLHttpRequest poskytuje niekoľko metód:

abort ()
Ukončí požiadavku.
getAllResponseHeaders ()
Vráti v reťazci zoznam všetkých hlavičiek.
open ("metóda", "url"[, asyncFlag[, "userName"[, "password"]]])
Priradí požiadavke cieľovú URL, metódu a ďalšie voliteľné parametre.
send (content)
Odošle požiadavku so zadaným obsahom.
setRequestHeader ("label", "value")
Pridá k požiadavke hlavičku.

Vlastnosti objektu XMLHttpRequest:

onreadystatechange
Funkcia pre obsluhu udalosti zmeny stavu objektu.
readyState
Číslo reprezentujúce aktuálny stav objektu: 0 = nenainicializovaný (uninitialized), 1 = nahráva (loading), 2 = nahraný (loaded), 3 = interaktívny (interactive), 4 = dokončený (complete)
responseText
Reťazec s údajmi, ktoré poslal server.
responseXML
XML (DOM-kompatibilný objekt) s údajmi, ktoré poslal server.
status
Návratový kód odpovede, ako napr. 404 pre nenájdenú stránku alebo 200 pre úspech.
statusText
Text, ktorý dopĺňa návratový kód odpovede.

Odoslanie požiadavky

Z predchádzajúceho výpisu metód objektu XMLHttpRequest vidíme, že pri otváraní novej požiadavky môžeme nastaviť, či má byť volanie synchrónne alebo asynchrónne. Predvolená hodnota je true, takže bez uvedenia tretieho argumentu metódy open bude volanie asynchrónne. Ak by sme nastavili tretí argument na false, volanie by bolo synchrónne. To by znamenalo, že hneď po zavolaní metódy send by sme mohli pracovať s odpoveďou, ku ktorej by sme sa dostali prostredníctvom vlastností responseText alebo responseXML. Avšak pri synchrónnom volaní musí klient na odpoveď čakať a počas tohto čakania nemôže nič robiť. Preto je vždy lepšie použiť asynchrónne volanie (okrem veľmi výnimočných prípadov).

Odoslanie požiadavky metódou POST

Najčastejšie sa používajú metódy open a send. Odoslanie požiadavky metódou POST by vyzeralo nasledovne:

function sendRequest (data, url)
{
	var xhr = createXhr ();

	if (xhr)
	{
		xhr.open ("POST", url);
		xhr.onreadystatechange = function () { if (receiveResponse (xhr)) xhr = null; };
		xhr.setRequestHeader ("Content-Type", "application/x-www-form-urlencoded");
		xhr.send (data);
	}

	return xhr;
}

Pri asynchrónnom volaní nastavíme obslužnú funkciu udalosti readystatechange, ktorá sa potom zavolá pri každej zmene stavu požiadavky. Tu by som chcel upozorniť na funkciu, ktorú sme v príklade použili ako obslužnú. Táto funkcia volá ďalšiu funkciu receiveResponse, ktorej v argumente posunieme objekt xhr. Dôležité je to, že po spracovaní odpovede, keď už viac nebude potrebné pristupovať k objektu xhr, vráti funkcia receiveResponse hodnotu true, aby bolo možné uvoľniť objekt xhr z pamäte. V mnohých ukážkach na webe takéto uvoľňovanie pamäte chýba, čo má za následok v niektorých prehliadačoch to, že pri každej požiadavke na server sa obsadí ďalší kus pamäte. Konkrétne ide o tzv. memory leaks v prehliadači Internet Explorer. Táto pamäť sa dá potom uvoľniť jedine reštartom prehliadača.

Pri požiadavkách odosielaných metódou POST musíme ešte nastaviť hlavičku požiadavky Content-Type na application/x-www-form-urlencoded, aby server vedel, že obsahom je zakódovaný formulár.

Odoslanie požiadavky metódou GET

Odoslanie požiadavky metódou GET je veľmi podobné, ale o niečo jednoduchšie. Keďže odosielané údaje sú zakódované už priamo v URL, netreba ich v metóde send nastavovať. Podobne netreba nastavovať hlavičku:

function sendRequest (data, url)
{
	var xhr = createXhr ();

	if (xhr)
	{
		xhr.open ("GET", url);
		xhr.onreadystatechange = function () { if (receiveResponse (xhr)) xhr = null; };
		xhr.send (null);
	}

	return xhr;
}

Nasledujúcim krokom bude prijatie a spracovanie odpovede nastavenou metódou receiveResponse.

Prijatie odpovede

Pri vytváraní požiadavky sme priradili objektu XMLHttpRequest obslužnú funkciu, ktorá sa volá pri výskyte udalosti readystatechange. Úlohou tejto obslužnej funkcie je spracovať prijatú odpoveď, prípadne ohlásiť chybu. Môže vyzerať nasledovne:

function receiveResponse (xhr)
{
	if (xhr.readyState == 4)
	{
		if (!xhr.status || xhr.status == 200)
			alert (xhr.responseText);
		else
			alert ("Error: " + xhr.statusText);

		return true;
	}
  
	return false;
}

Pri prijatí odpovede sa v prvom rade skontroluje vlastnosť readyState. Tá obsahuje kód stavu, v akom sa požiadavka nachádza. V drvivej väčšine prípadov chceme obslúžiť stav s kódom 4, kedy sa dokončilo prijatie odpovede. V komunikácii cez protokol HTTP má každá odpoveď svoj stav, ktorý je vyjadrený číslom vo vlastnosti status. Ak prišla odpoveď v poriadku, bude jej stav označený číslom 200. Iný stav znamená, že pravdepodobne nastala nejaká chyba. Ak spúšťame skript z lokálneho počítača bez použitia webového servera, môžeme pristupovať priamo k súborom na disku. Keďže v takomto prípade nekomunikujeme s webovým serverom, nemusí byť stav odpovede nastavený.

Táto funkcia vráti true v prípade, že požiadavku spracovala a objekt xhr nebude už viac potrebovať. V opačnom prípade vráti false. Ako bolo skôr spomenuté, takéto správanie sme si definovali kvôli správnemu uvoľňovaniu pamäte.

Záver

V tejto časti seriálu sme si ukázali základy práce s objektom XMLHttpRequest, ktoré by mali stačiť na vytvorenie jednoduchej komunikácie klienta so serverom. V ďalšej časti si ukážeme, ako by sa dala realizovať ekvivalentná komunikácia prostredníctvom skrytého rámca.

Čím sa líši táto ukážka od ostatných príkladov komunikácie klienta so serverom dostupných na Internete je hlavne to, že sa staráme aj o uvoľňovanie pamäte. Keď nepoužívame takúto komunikáciu intenzívne, nemusíme sa o neuvoľnenú pamäť príliš starať. Pri častej komunikácii však bez uvoľňovania pamäte hrozí kolaps aplikácie, webového prehliadača, prípadne celého systému z dôvodu vyčerpania systémových zdrojov.

Komentář k článku

1 Zadajte svou přezdívku:
2 Napište svůj komentář:
3 Pokud chcete dostat ban, zadejte libovolný text:

Zpět na články