XML pro web aneb od teorie k praxi, 14.díl - XmlHttpRequest

Dnes je na řadě představení zřejmě nejpokročilejšího nástroje, který má programátor XML-based aplikací v Javascriptu k dispozici - objektu XmlHttpRequest. S jeho využitím mohou aplikace dosáhnout řádově vyššího stupně inteligence, který spočívá v plnohodnotné komunikaci klient - server na bázi HTTP protokolu.
 minulých dvou dílech jsme se věnovali technikám, pomocí kterých můžeme načíst externí XML soubor do DOM dokumentu, převést jej na textový řetězec a obráceně. Jedna důležitá věc ale ještě chybí - odesílání XML dokumentu z klientského browseru na server. Minule jsme se tento nedostatek snažili obejít převodem na řetězec a odesláním pomocí formuláře. Dnes si ukážeme způsob, kterak posílat XML dokument na server mnohem efektivněji. I dnes počítejte s doprovodem nerozlučné dvojky prohlížečů Microsoft Internet Explorer (5.0 a vyšší) a Mozilla.

Možná největší překvapení, které nám MSIE a Mozilla připravily, je že způsob, jak provést odeslání XML dokumentu, má v obou prohlížečích téměř identickou podobu. Rozdíly jsou tentokrát opravdu minimální, zvláště pokud přihlédneme k faktu, že způsob řešení, kterým se dnes budeme zabývat, nemá oporu v žádných standardech a normách. Vysvětlení je ovšem celkem prozaické - s objektem XmlHttpRequest dostupným pro skriptování v prohlížeči (MSXML parseru) přišel Microsoft jako první a tak vývojáři Mozilly zvolili vcelku rozumné řešení - dobře vymyšlený a mocný nástroj implementovali s identickými názvy metod a vlastností.

Objekt XmlHttpRequest

Název XmlHttpRequest je svou zkratkovitou formou naprosto vystihující - tento objekt umožňuje odeslat XML dokument v těle HTTP požadavku. Aby komunikace na bázi HTTP protokolu byla maximálně komfortní, jsou možnosti objektu XmlHttpRequest mnohem širší, než jen prosté odeslání. Je možné přidávat hlavičky do HTTP požadavku, zpracovat odpověď serveru, přečíst HTTP hlavičky či status odpovědi, nebo přerušit provádění požadavku. Na všechny možnosti se nyní postupně podíváme.

Vytvoření objektu XmlHttpRequest

vytvoření objektu XmlHttpRequest je zřejmě jedinou podstatnou odlišností mezi MSIE a Mozillou. V Microsoft Internet Exploreru (jako už i v předchozích případech) je nutné objekt zavolat jako ActiveX komponentu.

var XHR = new ActiveXObject("Msxml2.XMLHTTP");

V Mozille má objekt XmlHttpRequest zcela logicky odlišný konstruktor.

var XHR = new XMLHttpRequest();

Inicializace HTTP požadavku

Inicializaci HTTP požadavku zajišťuje metoda open(). Metoda má dva povinné parametry a další tři parametry volitelné. Prvním parametrem je metoda (GET, POST) a druhým je URL, na které je požadavek zasílán (musí se jednat o absolutní URL včetně http://). Nepovinnými parametry jsou: async - logická proměnná určující, jestli je volání asynchronní. Výchozí hodnota je true. Parametr má velice podobný význam, jako vlastnost async při načítání DOM XML dokumentu. Dále user - uživatelské jméno a password (pro případ HTTP autentifikace).

XHR.open("POST", "http://www.nejaky-server.cz/adresar/script.php", false);

Nastavení HTTP hlaviček

Pokud potřebujeme k HTTP požadavku přidat či přenastavit HTTP hlavičky, máme k dispozici metodu setRequestHeader(). Metoda má dva parametry - header (název hlavičky, např. Content-type) a value (hodnota hlavičky, např. text/xml). Mějte na paměti, že za normálních okolností není potřeba nastavovat žádné hlavičky, neboť jsou nastaveny automaticky. Občas se ale může hodit možnost nějakou přidat.

XHR.setRequestHeader("User-agent", "XML requester 0.1");

Odeslání HTTP požadavku

Poté, co jsme voláním metody open() inicializovali HTTP požadavek (případně nastavili HTTP hlavičky), použijeme metodu send() k odeslání HTTP požadavku. Jediným parametrem této metody je body - tělo HTTP požadavku. Může jím být objekt DOM XML dokumentu nebo textový řetězec (případně input stream). Pokud je vložen DOM XML dokument, je převeden na řetězec.

XHR.send(xmlDoc);

Zjištění stavového kódu a hlaviček odpovědi

Stavový kód HTTP odpovědi je k dispozici prostřednictvím dvou vlastností objektu - status a statusText. První vrací stavový kód jako číslo, druhá celý stavový řádek jako string.

var statCode = XHR.status;

var statLine = XHR.statusText;

Pro zjištění obsahu HTTP hlaviček odpovědi můžeme použít dvou metod. Metoda getAllResponseHeaders() vrací textový řetězec obsahující všechny HTTP hlavičky. Hodnotu kterékoliv z jednotlivých HTTP hlaviček lze vypátrat metodou getResponseHeader(). Jediným parametrem metody je název hlavičky, jejíž hodnotu potřebujeme zjistit.

var headers = XHR.getAllResponseHeaders();

var contentType = XHR.getResponseHeader("Content-type");

Zpracování těla odpovědi

Tělo odpovědi na náš HTTP požadavek může obsahovat důležitá data. Aby bylo možné s těmito daty pracovat, máme možnost získat tělo odpovědi ve formě textového řetězce, nebo DOM XML dokumentu (pokud jej tělo obsahuje). K tomu jsou určené dvě vlastnosti - responseText a responseXML.

var textOdp = XHR.responseText;

var xmlDocOdp = XHR.responseXML;

Jak vidíte, objekt XmlHttpRequest se dá použít nejen pro poslání, ale i pro načtení XML dokumentu ze serveru - ani není nutné žádat o XML dokument skript, bez problémů si můžeme vyžádat přímo XML dokument. Na server v tom případě nemusíme zasílat žádný XML dokument.

XHR.open("POST", "http://www.nejaky-server.cz/adresar/doc.xml", false);
XHR.send();
var xmlDoc = XHR.responseXML;

V nejrozvinutější variantě představuje XmlHttpRequest výtečný nástroj pro plnohodnotnou komunikaci server - klient na bázi XML.

Průběh HTTP požadavku

Prostřednictvím vlastnosti readyState můžeme zjišťovat, v jaké fázi se nachází náš HTTP požadavek. Vlastnost vrací jednu z následujících hodnot, podle stavu HTTP požadavku:

  • 0 (UNINITIALIZED) - objekt XmlHttpRequest byl vytvořen, ale ještě nebyla volána metoda open()
  • 1 (LOADING) - před odesláním HTTP požadavku (metoda open() již byla zavolána, nikoliv však metoda send())
  • 2 (LOADED) - metoda send() již byla volána, stavový řádek a HTTP hlavičky jsou k dispozici, nikoliv však tělo odpovědi
  • 3 (INTERACTIVE) - část dat již byla přijata, vlastnost responseText obsahuje získaná nekompletní data
  • 4 (COMPLETED) - všechna data odpovědi byla přijata, všechny operace byly dokončeny.

V případě, že je parametr async metody send() nastaven na false, skript počká s prováděním další činnosti do té doby, než dojde k přijetí všech dat odpovědi. V opačném případě (async == true) je nutné ošetřit, v jaké fázi se HTTP požadavek nachází a podle toho rozhodnout, jestli požadovanou operaci (např. zpracování XML dokumentu zaslaného v tělě odpovědi) provést, nebo odložit.

Dokončení celé akce máme také plně pod kontrolou. V případě, že z nějakého důvodu potřebujeme přerušit provádění celého HTTP požadavku, lze zavolat metodu abort(), která vrátí požadavek do výchozího stavu 0 (UNINITIALIZED).

Popsali jsme si všechny metody a vlastnosti objektu XmlHttpRequest, které jsou shodné v Mozille a Internet Exploreru. Kromě výše popsaných existují ještě další, méně důležité metody a vlastnosti, ve kterých se ovšem oba prohlížeče odlišují. Máte-li zájem získat zebrubný přehled, prostudujte originální dokumentaci pro IE a Mozillu.

Pokud budete zkoušet posílat XML dokument pomocí objektu XmlHttpRequest na php skript, možná narazíte na problém, KDE nalézt samotný XML dokument? Není totiž k dispozici ve standardních GET či POST proměnných, jako v případě formulářovách dat. Pro ty, kteří si nebudou vědět rady, mám malou nápovědu - hledejte relativně málo známou proměnnou $HTTP_RAW_POST_DATA.

Příště se již budeme zpracování XML dokumentů pomocí Javascriptu věnovat naposledy. Před tím, než načneme poslední tématický okruh (XML a PHP), se ještě podíváme na XSLT transformace řízené Javascriptem.

Diskuze (9) Další článek: Poslanci hlasovali o novele tel. zákona

Témata článku: , , , , , , , , , , , , , , , , ,