Hlavní navigace

AJAX

Článek rozebírá různé možnosti umísťování interaktivních komponent na webové stránky a soustřeďuje se na jednu v současné době poměrně populární. Díky technologii Asynchronous JavaScript and XML je možné z webového prohlížeče elegantně komunikovat s webovým serverem a vyměňovat si s ním data, která se mohou ihned uložit na serveru nebo naopak zobrazit u klienta.

Tweetni to Odměnte autora  Jak to funguje?

Pokud je na stránce nějaká dynamická komponenta, např. anketa, hlasování nebo konec konců i diskuse, dá se k jejímu zpracování přistoupit mnoha různými způsoby:

  • Tradiční řešení spočívá v tom, že akce je realizována běžným odkazem nebo formulářem a po jejím provedení se nahraje celá stránka znovu. Nevýhody jsou zřejmé – pomalost a pracnost vracení stránky na místo, které bylo zobrazeno před provedením akce.
  • Zpracování akce v nově otevřeném okně netrpí neduhy tradičního řešení, řada uživatelů je ale na otevírání nových oken alergická, obzvlášť když je to jenom kvůli oznámení, že jejich hlas byl započten. Toto řešení navíc původní stránku obvykle neaktualizuje aktuálními daty.
  • Umístění komponent do samostatného rámu je nejelegantnější u jednoduchých stránek, které využívají dynamické komponenty provozované na jiném serveru. U větších serverů má ale i toto řešení své nevýhody – ve striktním HTML jsou rámy zakázané a stažení každé komponenty znamená další požadavek na webový server.
  • Využít skriptování u klienta je pravděpodobně nejpracnější, ale zároveň přináší největší uživatelský prožitek. Realizovat se dá několika způsoby – přesměrováním akce do neviditelného rámu, který skriptem změní původní stránku, dynamickým vytvořením elementu script a jeho umístěním do HTML dokumentu nebo pomocí objektu XMLHttpRequest, který byl pro komunikaci skriptů se serverem přímo navržen.
  • Pro hodnocení komentářů na Rootu je použit poměrně neobvyklý přístup, kdy se hlasy ukládají u klienta do cookie a na server se odešlou teprve až s návštěvou další stránky. Vzhledem k množství hodnocených komentářů se mi jeví tento přístup jako velice rozumný, protože jinak by počet požadavků na server neúměrně vzrostl, použít ho však lze jen ojediněle.
  • Existují samozřejmě i další možnosti, např. umístění komponenty do Flashe, ty ale není možné použít vždy.

Pro použití objektu XMLHttpRequest se ustálil pojem AJAX, přestože korektní použití tohoto objektu nemusí odpovídat ani jednomu slovu ve zkratce – komunikace nemusí být asynchronní, jako skriptovací jazyk nemusí být použit JavaScript a data se nemusí přenášet pouze pomocí XML. Naopak AJAX se dá výše naznačenými způsoby zajistit i bez objektu XMLHttpRequest.

Příklad – realizace ankety v PHP

Na jednoduchém příkladu si ukážeme, jak se AJAX dá použít pro zpracování ankety. Důležitá část skriptů je univerzální a použitelná i v dalších komponentách.

Hlavní stránka se od ostatních řešení příliš lišit nebude. V případě vypnutého JavaScriptu nebo obecně nefunkčnosti technologie AJAX u klienta se navštíví běžný odkaz, který aktualizuje databázi a stránku celou překreslí. Pro kontrolu toho, jestli uživatel ještě nehlasoval, se používá cookie s platností jeden měsíc, podle potřeb je možné tuto kontrolu samozřejmě změnit. Vazbu na AJAX v tomto souboru zajišťuje volání funkce anketa_hlasovat.

<?php
// uložení odpovědi v případě vypnutého JavaScriptu
if (isset($_GET["anketa"]) && !isset($_COOKIE["anketa"])) { // primitivní kontrola toho, jestli uživatel ještě nehlasoval
    setcookie("anketa", $_GET["anketa"], strtotime("+1 month"));
    $_COOKIE["anketa"] = $_GET["anketa"];
    mysql_query("UPDATE anketa SET pocet = pocet + 1 WHERE id = " . intval($_GET["anketa"]));
}

// zobrazení ankety
echo "<h3>Anketa</h3>\n";
$result = mysql_query("SELECT * FROM anketa");
echo "<table border='1' id='anketa'>\n";
while ($row = mysql_fetch_assoc($result)) {
    $odpoved = htmlspecialchars($row["odpoved"]);
    if (!isset($_COOKIE["anketa"])) {
        $odpoved = "<a href='?anketa=$row[id]' onclick='return !anketa_hlasovat($row[id]);'>$odpoved</a>";
    }
    echo "<tr><td class='odpoved'>$odpoved</td><td id='pocet$row[id]'>$row[pocet]</td></tr>\n";
}
echo "</table>\n";
echo "<span id='stav-anketa'></span>\n";
mysql_free_result($result);
?> 

Největší část funkčnosti zajišťuje následující JavaScriptový kód. Funkce send_xmlhttprequest je obálka nad objektem XMLHttpRequest, která zajistí vytvoření správného objektu v závislosti na schopnostech prohlížeče, inicializuje požadavek a nastaví mu případné hlavičky a tělo, prováže ho s obsluhou události a odešle ho. Funkce anketa_hlasovat tuto funkci využívá a kromě toho znemožní opětovné hlasování vymazáním odkazů a překreslí anketu se započteným hlasem uživatele. V neposlední řadě informuje uživatele o tom, že se ukládají výsledky – vzhledem k tomu, že uživatelé na tento způsob modifikace stránek nemusí být zvyklí, je jejich informování poměrně důležité. Funkce anketa_obsluha přiřazená k obsluze události onreadystatechan­ge se volá při každé změně stavu, a pokud je požadavek dokončen (readyState má hodnotu 4), aktualizuje data na základě momentálního počtu odpovědí a informuje uživatele o dokončení požadavku.

<script type="text/javascript">
/** odeslání XMLHttp požadavku
@param function obsluha funkce zajišťující obsluhu při změně stavu požadavku, dostane parametr s XMLHttp objektem
@param string method GET|POST|...
@param string url URL požadavku
@param string [content] tělo zprávy
@param array [headers] pole předaných hlaviček ve tvaru { 'hlavička': 'obsah' }
@return bool true v případě úspěchu, false jinak
*/
function send_xmlhttprequest(obsluha, method, url, content, headers)
{
    var xmlhttp = (window.XMLHttpRequest ? new XMLHttpRequest : (window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : false));
    if (!xmlhttp) {
        return false;
    }
    xmlhttp.open(method, url);
    xmlhttp.onreadystatechange = function() {
        obsluha(xmlhttp);
    };
    if (headers) {
        for (var key in headers) {
            xmlhttp.setRequestHeader(key, headers[key]);
        }
    }
    xmlhttp.send(content);
    return true;
}
</script> 

Za zmínku stojí, že vytvořený objekt xmlhttp se obslužné funkci předává jako parametr. V tomto jednoduchém případě by to mohla být i globální proměnná, ale vzhledem k tomu, že na stránce může být dynamických komponent více, je nutné mezi nimi rozlišovat. Pokud by se použila globální proměnná a nějaká komponenta by vytvořila nový požadavek ještě před dokončením předešlého, vedlo by to k jeho nedokončení. Je potřeba pamatovat na to, že zpracování je asynchronní.

<script type="text/javascript">
function anketa_hlasovat(hlas)
{
    // odeslání požadavku na aktualizaci dat
    if (!send_xmlhttprequest(anketa_obsluha, 'GET', 'anketa_rpc.php?anketa=' + hlas)) {
        return false;
    }
    document.getElementById('pocet' + hlas).innerHTML++; // zobrazení hlasu u klienta
    // znemožnění opětovného hlasování smazáním odkazů
    for (var key in document.getElementById('anketa').getElementsByTagName('td')) {
        var val = document.getElementById('anketa').getElementsByTagName('td')[key];
        if (val.className == 'odpoved') {
            val.innerHTML = val.firstChild.innerHTML;
        }
    }
    document.getElementById('stav-anketa').innerHTML = 'Ukládá se';
    return true;
}

function anketa_obsluha(xmlhttp)
{
    if (xmlhttp.readyState == 4) {
        // aktualizace odpovědí na základě aktuálního stavu
        var odpovedi = xmlhttp.responseXML.getElementsByTagName('odpoved');
        for (var i=0; i < odpovedi.length; i++) {
            document.getElementById(odpovedi[i].getAttribute('id')).innerHTML = odpovedi[i].firstChild.data;
        }
        document.getElementById('stav-anketa').innerHTML = 'Uloženo';
    }
}
</script> 

Skript anketa_rpc.php je velice jednoduchý – zkontroluje, jestli uživatel ještě nehlasoval, započte jeho hlas a zpět odešle jednoduché XML s aktuálním počtem odpovědí. Jak již bylo řečeno, nemusí spolu skripty komunikovat pomocí XML, u strukturovaných dat je to však poměrně praktické. Pokud by skript generoval nestrukturovaná data, lze k nim z JavaScriptu přistoupit přes vlastnost responseText.

<?php
if (!isset($_COOKIE["anketa"])) {
    setcookie("anketa", $_GET["anketa"], strtotime("+1 month"));
    mysql_query("UPDATE anketa SET pocet = pocet + 1 WHERE id = " . intval($_GET["anketa"]));
}

header("Content-Type: text/xml");
echo "<anketa>\n";
$result = mysql_query("SELECT * FROM anketa");
while ($row = mysql_fetch_assoc($result)) {
    echo "<odpoved id='pocet$row[id]'>$row[pocet]</odpoved>\n";
}
mysql_free_result($result);
echo "</anketa>\n";
?> 

Objekt XMLHttpRequest umožňuje i odesílání dat metodou POST. Opět lze poslat XML dokument, je ale možné použít i hlavičku Content-Type: application/x-www-form-urlencoded a data poslat standardně URL-zakódovaná (jednotlivé části funkcí encodeURICompo­nent). Z takto poslaných dat PHP vytvoří standardní proměnné.

AJAX se samozřejmě dá použít i na spoustu dalších věcí. Zmíněny byly další dynamické komponenty stránky, dobře viditelné je použití u tzv. našeptávačů nebo u mapových aplikací, použít se dá např. i pro předběžnou kontrolu unikátnosti uživatelského jména u klienta. Fantazii se meze nekladou, důležité je ale vždy zajistit, aby aplikace byla použitelná i bez této funkce. Nevhodné je také AJAXem nahradit např. běžný přechod mezi stránkami, protože uživatelé potom nemohou používat historii a mohou být zmateni, že se stránky chovají jinak, než jsou zvyklí.

Jakub Vrána

Jakub Vrána

Autor se živí programováním v PHP, podílí se na jeho oficiální dokumentaci, vyučuje ho na MFF UK a vede odborná školení. Poznámky si zapisuje na weblog PHP triky.

Ohodnoťte jako ve škole:
Průměrná známka 2,89
Tweetni to Odměnte autora  Jak to funguje?

Školení: Obsahová strategie a content marketing

DW - Školeny webcopywritingu
  • Proč je obsahový marketing výrazným trendem
  • Jak navrhnout užitečnou obsahovou strategii
  • Jaký obsah využít a které nástroje vám pomohou
  • Jak zlepšit workflow a výsledky copywritingu

Detailní informace o školení content strategy »

       

Přehled názorů

zdrojak + ukazka
spud 3. 10. 2005 08:24
Nový
└ 
Re: zdrojak + ukazka
František Brakon 3. 10. 2005 09:15
Nový
 
├ 
Re: zdrojak + ukazka
Pepa 3. 10. 2005 09:32
Nový
 
├ 
Re: zdrojak + ukazka
spud 3. 10. 2005 10:56
Nový
 
│
└ 
Re: zdrojak + ukazka
František Brakon 3. 10. 2005 11:11
Nový
 
│
 
├ 
Re: zdrojak + ukazka
Jozef Kosoru 4. 10. 2005 14:10
Nový
 
│
 
│
└ 
Re: zdrojak + ukazka
Kočka 2. 6. 2006 14:24
Nový
 
│
 
│
 
└ 
Re: zdrojak + ukazka
Dragonn 25. 2. 2008 23:23
Nový
 
│
 
└ 
Re: zdrojak + ukazka
YF 7. 10. 2005 21:25
Nový
 
├ 
Re: zdrojak + ukazka
Jakub Vrána 3. 10. 2005 14:45
Nový
 
│
├ 
Re: zdrojak + ukazka
Petr Mach 4. 10. 2005 13:11
Nový
 
│
├ 
Re: zdrojak + ukazka
cube 5. 10. 2005 12:46
Nový
 
│
└ 
Re: zdrojak + ukazka
omg 3. 1. 2010 12:33
Nový
 
└ 
Re: zdrojak + ukazka
anonymní uživatel 25. 1. 2007 00:58
Nový
testovani Ajaxu
rdk 3. 10. 2005 09:31
Nový
├ 
Re: testovani Ajaxu
martin 3. 10. 2005 11:08
Nový
│
└ 
Re: testovani Ajaxu
RonyMcNamara 3. 10. 2005 11:44
Nový
└ 
Re: testovani Ajaxu
anonymní uživatel 3. 10. 2005 13:40
Nový
Microsoft kouká lidem přes rameno
Gummi 3. 10. 2005 12:07
Nový
├ 
Re: Microsoft kouká lidem přes rameno
František Brakon 3. 10. 2005 12:24
Nový
│
└ 
Re: Microsoft kouká lidem přes rameno
Tomáš Marek 3. 10. 2005 12:52
Nový
│
 
├ 
Re: Microsoft kouká lidem přes rameno
Ondrej Ivanič 3. 10. 2005 15:17
Nový
│
 
│
└ 
Re: Microsoft kouká lidem přes rameno
Radek Z. 5. 10. 2005 08:33
Nový
│
 
│
 
└ 
ADD: Ta cp1250
BezMozek 18. 11. 2005 20:40
Nový
│
 
│
 
 
└ 
Re: ADD: Ta cp1250
pogik 7. 2. 2006 20:37
Nový
│
 
└ 
Re: Microsoft kouká lidem přes rameno
luks 3. 10. 2005 21:06
Nový
│
 
 
└ 
Re: Microsoft kouká lidem přes rameno
Martin Hassman 3. 10. 2005 21:10
Nový
│
 
 
 
└ 
Re: Microsoft kouká lidem přes rameno
Michal Ludvig 4. 10. 2005 04:40
Nový
└ 
Re: Microsoft kouká lidem přes rameno - ATLAS
optik 3. 10. 2005 14:22
Nový
 
├ 
Re: Microsoft kouká lidem přes rameno - ATLAS
Kana 3. 10. 2005 20:55
Nový
 
│
└ 
Re: Microsoft kouká lidem přes rameno - ATLAS
Farin 4. 10. 2005 16:39
Nový
 
├ 
Re: Microsoft kouká lidem přes rameno - ATLAS
BoodOk 3. 10. 2005 21:39
Nový
 
│
└ 
Re: Microsoft kouká lidem přes rameno - ATLAS
Optik 4. 10. 2005 13:02
Nový
 
│
 
└ 
Re: Microsoft kouká lidem přes rameno - ATLAS
anonymní uživatel 5. 10. 2005 09:37
Nový
 
└ 
Re: Microsoft kouká lidem přes rameno - ATLAS
Petr Mach 4. 10. 2005 13:02
Nový
Doplneni - omezeni
Leo 4. 10. 2005 22:20
Nový
└ 
Re: Doplneni - omezeni
Martin Hassman 4. 10. 2005 23:17
Nový
Alternativa pres <img src=...
Honza Malík 9. 11. 2005 23:51
Nový
Xajax
anonymní uživatel 16. 1. 2006 19:44
Nový
Takhle je to správně
Mike 13. 4. 2010 07:53
Nový
AJAX project solutions at AssignmentExpert.com
AJAX homework help 8. 11. 2010 17:23
Nový
       

Tento text je již více než dva měsíce starý. Chcete-li na něj reagovat v diskusi, pravděpodobně vám již nikdo neodpoví. Pro řešení aktuálních problémů doporučujeme využít naše diskusní fórum.

Zasílat nově přidané příspěvky e-mailem