Your Search Results

    AJAX/Jak_začít

     

    Tento článek vás provede základy AJAXu a dá vám d začátku dva jednoduché praktické příklady.

    Co je to AJAX?

    Asynchronní JavaScript a XML (angl. Asynchronous JavaScript and XML, zkr. AJAX) je nově vytvořený termín pro dvě mocné vlastnosti webových prohlížečů. Byly k dispozici léta, ale až doposud byly mnoha webovými vývojáři přehlíženy, než se staly hitem aplikace typu Gmail, Google Suggest a Google Maps.

    Zmíněné dvě vlastnosti jsou tyto:

    • zasílání žádostí na server bez nutnosti znovu-načtení stránky
    • zpracovávání XML dokumentů

    Krok 1 – říct "Prosím!" aneb jak vytvořit HTTP požadavek

    K vytvoření HTTP požadavku na server použitím JavaScriptu potřebujete instanci třídy, která tuto funkcionalitu poskytuje. Taková třída byla původně představena v Internet Exploreru jako objekt ActiveX zvaný XMLHTTP. Prohlížeče Mozilla, Safari a další následně začlenily třídu XMLHttpRequest, která podporuje metody a vlastnosti původního objektu ActiveX od Microsoftu.

    Instanci (objekt) požadované třídy vytvoříte takto:

    if (window.XMLHttpRequest) { // Mozilla, Safari, Opera, Konqueror, ...
        http_zadost = new XMLHttpRequest();
    } else if (window.ActiveXObject) { // Internet Explorer
        http_zadost = new ActiveXObject("Microsoft.XMLHTTP");
    }
    

    (Pro zjednodušení byl předchozí kód uraven oproti běžnému kódu používanému k vytvoření XMLHTTP instancí. Příklad více ze života naleznete ve třetím kroku tohoto článku.)

    Některé verze prohlížeče Mozilla nebudou pracovat správně, pokud odpověď ze serveru nemá hlavičku XML mime-type. Potřebujete-li toto obejít, můžete použít zvláštní volání metody k potlačení hlavičky odeslané serverem v případě, že není text/xml.

    http_zadost = new XMLHttpRequest();
    http_zadost.overrideMimeType('text/xml');
    

    Dále se potřebujete rozhodnout, co chcete dělat po přijetí odpovědi ze serveru. V této chvíli potřebujete říct objektu HTTP žádosti, která funkce v JavaScriptu bude zpracovávat odpověď. Můžete tak udělat nastavením vlastnosti onreadystatechange objektu na jméno JavaScriptové funkce, kterou se chystáte použít, např.:

    http_zadost.onreadystatechange = jmenoFunkce;

    Všimněte si, že za jménem funkce nestojí žádné parametry ani závorky, protože namísto volání této funkce prostě přidělujete odkaz. Namísto předání jména funkce můžete také využít JavaScriptovou techniku, definující funkci za běhu (tzv. "anonymní funkce"), a definovat události, které budou zpracovávat odpověď přímo, takto:

    http_zadost.onreadystatechange = function(){
        // udělej něco
    };
    

    Poté, co se rozhodnete, jak zpracovávat odpovědi, potřebujete vytvořit opravdovou žádost a tedy zavolat metody open() a send() na třídu HTTP žádosti, např. takto:

    http_zadost.open('GET', 'http://www.example.org/nejaky.soubor', true);
    http_zadost.send(null);
    
    • První parametr volající open() je metoda HTTP žádosti - GET, POST, HEAD či jiná, která je podporována vaším serverem. Dodržujte velká písmena v názvech metod, jak uvádí HTTP standard - některé webové prohlížeče (například Firefox) jinak nemusí žáfost zpracovat. Více informací o dostupných metodách HTTP žádostí naleznete ve specifikaci na W3C
    • Druhý parametr je odkaz na stránku, na kterou posíláte žádost. Z důvodu větší bezpečnosti nemůžete volat domény třetí strany. Ujistěte se, že na všech vašich stránkách používáte přesný název domény, jinak může při volání metody open() dojít k chybě 'přístup odepřen'. Běžnou chybou je přistupování k vaší stránce jako <tt>domena.tld</tt>, ale pokus o volání stránky jako <tt>www.domena.tld</tt>.
    • Třetí parametr nastavuje, je-li žádost asynchronní. Pokud je nastavena na true, JavaScriptová funkce pokračuje, zatímco odpověď od serveru ještě nebyla. Proto to první "A" ve slově "AJAX".

    Parametr metody send() může obsahovat jakákoliv data, která chcete odeslat v žádosti na server přes POST. Data dotazu by měla být ve tvaru řetězce, např. takto:

    jmeno=hodnota&jinejmeno=dalsihodnota&so=on

    Povšimněte si, že pokud chcete poslat data přes POST, musíte změnit MIME typ žádosti:

    http_zadost.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    

    Server jinak zahodí data tímto způsobem odeslaná.

    Krok 2 – "Jdeme na to!" aneb obsluha odpovědi ze serveru

    Vzpomeňte si, že když jste posílali svou žádost, uváděli jste jméno funkce, která slouží ke zpracování odpovědi:

    http_zadost.onreadystatechange = jmenoFunkce;

    Podívejme se, co by taková funkce měla dělat. Zaprvé, funkce potřebuje zkontrolovat stav žádosti. Pokud má stav hodnotu 4, značí to, že byla přijata kompletní odpověď ze serveru a vy ji můžete v pořádku zpracovat.

    if (http_zadost.readyState == 4) {
        // Vše je v pořádku, odpověď byla přijata
    } else {
        // Ještě nejsem připravený
    }
    

    Úplný seznam hodnot readyState je následující:

    • 0 (neinicializováno)
    • 1 (nahrávání)
    • 2 (nahráno)
    • 3 (zpracovávano)
    • 4 (hotovo)

    (Zdroj)

    Další věc ke kontrole je stavový kód z odpovědi HTTP serveru. Všechny možné kódy jsou uvedené na webu W3C. Pro naše účely jsme se zajímali pouze o odpověď 200 OK.

    if (http_zadost.status == 200) {
        // Perfektní!
    } else {
        // Byl problém s dotazem, 
        // například kód odpovědi byl možná 404 (Stránka nenalezena)
        // nebo 500 (Interní chyba serveru)
    }
    

    Poté, co zkontrolujete stav žádosti a stavový kód HTTP odpovědi, je jen na vás, jak naložíte s daty, která vám server zaslal. Máte dvě možnosti přístupu k těmto datům:

    • http_zadost.responseText – odpověď serveru jako textový řetězec.
    • http_zadost.responseXML – odpověď serveru jako XMLDocument objekt, který můžete procházet pomocí DOM funkcí v JavaScriptu

    Krok 3 – "Teď vše dohromady!" - jednoduchý příklad

    Dejme to vše dohromady a udělejme jednoduchou HTTP žádost. Náš JavaScript zažádá o HTML dokument test.html, který obsahuje text "Jsem test!". Obsah tohoto souboru následně zobrazíme v JavaScriptovém upozornění.

    <script type="text/javascript" language="javascript">
        function vytvoritZadost (url) {
            var http_zadost = false;
    
            if (window.XMLHttpRequest) { // Mozilla, Safari, Opera, Konqueror...
                http_zadost = new XMLHttpRequest();
                if (http_zadost.overrideMimeType) {
                    http_zadost.overrideMimeType('text/xml');
                    // Podívejte na poznámku o tomto řádku níže
                }
            } else if (window.ActiveXObject) { // Internet Explorer
                try {
                    http_zadost = new ActiveXObject("Msxml2.XMLHTTP");
                } catch (e) {
                    try {
                        http_zadost = new ActiveXObject("Microsoft.XMLHTTP");
                    } catch (e) {}
                }
            }
    
            if (!http_zadost) {
                alert('Giving up :( Nemohu vytvořit XMLHTTP instanci');
                return false;
            }
            http_zadost.onreadystatechange = function() { stavObsahu(http_zadost); };
            http_zadost.open('GET', url, true);
            http_zadost.send(null);
    
        }
    
        function stavObsahu(http_zadost) {
    
            if (http_zadost.readyState == 4) {
                if (http_zadost.status == 200) {
                    alert(http_zadost.responseText);
                } else {
                    alert('Byl problém se žádostí.');
                }
            }
    
        }
    </script>
    <span
        style="cursor: pointer; text-decoration: underline"
        onclick="vytvoritZadost('test.html')">
            Vytvořit žádost
    </span>
    


    V tomto příkladu:

    • Uživatel klikne na odkaz "Vytvořit žádost" ve webovém prohlížeči.
    • Zavolá funkci vytvoritZadost() s parametrem – jméno HTML souboru test.html, uloženého ve stejném adresáři jako volající skript.
    • Vytvoří se požadavek, řízení je předáno funkci stavObsahu()
    • stavObsahu() zkontroluje, byla-li žádost přijata. Pokud je vše pořádku, obsah souboru se objeví na obrazovce v upozornění JavaScriptu.

    Příklad je k dispozici zde vč. zdrojového souboru test.html zde.

    Poznámka 1: Výše uvedený řádek http_zadost.overrideMimeType('text/xml'); způsobí chybu v JavaScriptové konzole ve Firefoxu 1.5 a pozdějším, jak je zdokumentováno na https://bugzilla.mozilla.org/show_bug.cgi?id=311724 , pokud stránka volaná XMLHttpRequest není validní XML (např. prostý text). To je vlastně správné chování; tento článek bude brzy upraven, aby tuto změnu reflektoval.

    Poznámka 2: Pokud posíláte požadavek na části kódu, která vrátí XML, spíše než na statický XML soubor, musíte nastavit některé hlavičky odpovědi, pokud má vaše stránka pracovat kromě Mozilly i v Internet Exploreru. Pokud nenastavíte hlavičku Content-Type: application/xml, IE vrátí chybu JavaScriptu 'Očekáván objekt' po řádce, kde se snažíte přistupovat k XML elementům. Pokud nenastavíte hlavičku Cache-Control: no-cache, prohlížeč uloží odpověď ve vyrovnávací paměti a znovu neodešle další požadavky, což stíží ladění.

    Poznámka 3: Pokud je proměnná http_zadost používána globálně, souběžná volání funkce vytvoritZadost() se mohou navzájem potlačit, což způsobí souběh. Deklarování proměnné http_zadost lokálně dané funkci a její předání funkci souběhu stavObsahu() zabrání.

    Poznámka 4: K zaregistrování funkce, předávané onreadystatechange, nemůžete použít žádné argumenty. Proto následující kód není funkční:

    http_request.onreadystatechange = stavObsahu(http_zadost); // (nefunguje)
    

    Abyste úspěšně funkci zaregistrovali, můžete buď předat argumenty nepřímo prostřednictvím anonymní funkce, nebo použít http_request jako globální proměnnou. Následují příklady:

    http_zadost.onreadystatechange = function() { stavObsahu(http_zadost); };  //1 (simulace žádosti)
    http_zadost.onreadystatechange = stavObsahu;                               //2 (globální proměnná)
    

    Metoda 1 vám umožňuje zpracovat několik požadavků současně, zatímco metoda 2 se používá, když http_zadost je globální proměnná.

    Poznámka 5: V případě komunikační chyby (jako výpadek webového serveru), bude vrácena výjimka v metodě onreadystatechange při pokusu o přistup k proměnné .status. Ujistěte se, že takovou výjimku zpracováváte. (Viz. https://bugzilla.mozilla.org/show_bug.cgi?id=238559).

    function stavObsahu(http_zadost) {
    
            try {
                if (http_zadost.readyState == 4) {
                    if (http_zadost.status == 200) {
                        alert(http_zadost.responseText);
                    } else {
                        alert('Byl problém se žádostí.');
                    }
                }
            }
            catch( e ) {
                alert('Zachycená výjimka: ' + e.description);
            }
    
        }
    

    Krok 4 – "Akta X" aneb práce s XML odpovědí

    V předešlém příkladě jsme použili pro přijetí odpovědi na HTTP žádost vlastnost responseText objektu odpovědi, která obsahovala obsah souboru <tt>test.html</tt>. Nyní si to zkusíme pomocí vlastnosti responseXML.

    Nejprve si vytvoříme validní XML dokument, který později vyžádáme. Dokument (<tt>test.xml</tt>) obsahuje následující:

    <?xml version="1.0" ?>
    <root>
        Jsem test!
    </root>
    

    Ve skriptu potřebujeme pouze změnit řádek se žádostí:

    ...
    onclick="vytvoritZadost('test.xml')">
    ...
    

    Pak v stavObsahu() potřebujeme nahradit řádek s alert(http_zadost.responseText); na:

    var xmldoc = http_zadost.responseXML;
    var koren_uzlu = xmldoc.getElementsByTagName('root').item(0);
    alert(koren_uzlu.firstChild.data);
    

    Tento kód přijme objekt XMLDocument, předaný pomocí responseXML, a použije DOM metody k přístupu k datům obsaženým v takovém XML dokumentu. K dispozici je soubor <tt>test.xml</tt> zde a upravený testovací skript zde.

    Více o DOM metodách naleznete v dokumentaci o implementaci DOM v Mozille.

    Document Tags and Contributors

    Contributors to this page: DJ.Maca, teoli, Triceo, Giles, Pawell
    Last updated by: teoli,