O webu
AJAX

Od IE 7 je napříč prohlížeči nejednodušší funkční řešení následující:

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
  if (xhr.readyState == 4) alert(xhr.responseText);
}
xhr.open('GET', "url-stranky");
xhr.send();

Pro případnou podporu IE 6 a starších je třeba použít ActiveXObject.

var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();

JSON

Zkratka JSON znamená JavaScript Object Notation, tj. jedná se o textový obsah, který je ve formátu jako se v JS vytváří objekty. Obsah je typu {klic: "hodnota"} a v PHP jde elegantně vytvořit z běžného pole funkcí json_encode.

V xhr.responseText bude po vykonání požadavku na URL obsah dané stránky (co se stahuje si lze snadno ověřit zadáním stejné URL do prohlížeče). Neřeší se, zda se jedná o HTML, JSON nebo cokoliv jiného. Tvůrce si tedy může vybrat, který formát bude preferovat a používat.

Pokud není příliš obtížné / je možné stránku na straně serveru upravit tak, aby v určitých situacích (např. speciální parametr v URL) vracela JSON pouze s potřebnými daty, bude se s výsledkem z xhr.responseText lépe pracovat.

Vyzobávat potřebná data je možné i z původního HTML souboru včetně <!doctype>, hlavičky a podobně, a to buď regulárními výrazy nebo standardními funkcemi DOMu. Je potom ale otázka, zda asynchronní načítání vůbec používat. V takovém případě to vyjde stejně jako běžný přechod na cílovou URL (stáhne se stejné množství dat).

Řešení AJAXu s JSONem

Hotová funkce pro zpracovávání JSONu získaného AJAXem může vypadat následovně:

function ajax(url, callback) {
  var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
  xhr.onreadystatechange = function () {
    if (xhr.readyState == 4) callback(eval('(' + xhr.responseText + ')'));
  };
  xhr.open('GET', url);
  xhr.send();
}

Použití pro JSON obsah {url: "http://jecas.cz", nazev: "Je čas"} (živá ukázka):

ajax("url-stranky", function(data) {
  alert(data.url); // vypíše „http://jecas.cz“
  alert(data.nazev); // vypíše „Je čas“
});

Pro zpracovávání prostého textu nebo HTML stačí z funkce ajax odstranit eval a pracovat s textovým řetězcem (ukázka).

AJAX na jinou doménu

Kvůli bezpečnosti je možné používat AJAX jen v rámci stejné domény. Tedy z domény example.com se dostaneme na stránku example.com/stranka. Ale už ne na jiny.example.com, www.example.com (AJAX nefunguje ani na subdoménách) nebo jiny-example.com.

Řešení je

  1. Zajistit, aby potřebný obsah byl dostupný na URL z téže domény.
  2. Vytvořit na stejné doméně skript, který z cizí domény stránku stáhne. K takovému obsahu už se AJAX dostane.
  3. Obsah z cizí domény připojovat jako externí skript (tzv. JSONP).

JSONP

JSONP je JavaScriptový objekt s „vycpávkou“. Funguje to tak, že se běžný JSON umístí do argumentu nějaké funkce (to je ta vycpávka) a celé se to připojí jako externí JavaScript (připojovat skripty je možné i z jiné domény).

Takový JSONP soubor / externí JS (ve skutečnosti třeba v PHP dynamicky generovaný soubor na straně serveru) může vypadat následovně:

vlastniFunkce({url: "http://jecas.cz", nazev: "Je čas"})

V momentě, kdy tento skript připojíme (a on se stáhne a vykoná), se zavolá funkce vlastniFunkce (kterou si na cílovém webu nadeklarujeme) a budou jí tak předána data, která může dále libovolně zpracovávat.

Kromě zpracovávání JSONu ale nic nebrání tuto techniku připojování externího skriptu využít s jiným typem dat, tj. třeba vůbec nepoužívat JSON a data rovnou nastavit jako parametry funkce:

vlastniFunkce("http://jecas.cz", "Je čas")

Potenciální risiko JSONP řešení je v tom, že si do stránky připojíme cizí skript, který v případě napadení může vytvořit neřešitelný XSS. Proto je tuto techniku vhodné používat jen u důvěryhodných stránek.

Dynamické připojení skriptu

Připojování skriptu může zajišťovat funkce ve stylu.

function pripojitJs(url) {
  var s = document.createElement("script");
  s.src = url;
  document.getElementsByTagName("head")[0].appendChild(s);
}

Živá ukázka JSONP řešení.

Indikace průběhu

Po vyvolání akce, která začne AJAXem stahovat nějaká data, zvlášť v případě, že to bude trvat déle, je vhodné dát uživateli najevo, že se něco děje; to může znázorňovat.

  1. Animovaný obrázek, který se objeví po kliknutí a bude skryt callback funkcí.
  2. Změna kursoru na wait (opět je nutné zajistit vrácení kursoru po dokončení akce). Toto řešení není moc použitelné u dotykem ovládaných zařízení.
  3. Nástroj PACE nabízí hotové řešení průběhu načítání.

Odesílání formulářů AJAXem

AJAXové odesílání formulářů se dá řešit dvěma způsoby. Buď projít všechna formulářová pole JavaScriptem a sestavit z nich řetězec ve stylu prvniPole=hodnota&druhePole=hodnota (hotová funkce).

Nebo formulář odesílat do skrytého rámu, který podobně jako JSONP řešení zavolá funkci z původní stránky s předanými daty.

Skript, na který se formulář odešle vytvoří výstup:

<script>
window.top.window.vlastniFunkce({url: "http://jecas.cz", nazev: "Je čas"});
</script>

Tím se obsah (JSON) předá funkci v nadřazené stránce skrytému rámu. Výhoda tohoto řešení je v tom, že o indikaci se postará prohlížeč standardní cestou.

Pro AJAXový upload je to jediná možnost funkční napříč prohlížeči. Tento způsob se dá bez problému použít i pro běžný formulář.

Pseudo AJAX

Pro situace, kde není potřeba zpětná vazba, si je možné vystačit bez XMLHttpRequestu, JSONP řešení nebo odesílání do skrytého rámu. Chceme-li pouze odeslat nějaká data bez obnovování stránky, existují další možnosti.

Před použitím tohoto způsobu je nutné pečlivě zvážit, zda absence odezvy nebude pro návštěvníka matoucí.

HTTP hlavička 204

HTTP hlavička 204 (No Response / No Content) znamená, že byl požadavek úspěšně zpracován, ale výsledkem není žádný výstup k navrácení klientovi. Za následek to má, že prohlížeč na takovou stránku nepřejde, ale skript běžící na dané URL se normálně vykoná.

<?php
header('HTTP/1.0 204 No Content', true, 204);
// Nějaká akce
exit;

Pingnutí obrázkem

Této techniky často využívají různé měřicí skripty. Do HTML kódu umístíme obrázek s cílem skriptu, který po vykonání své činnosti vrátí průhledný 1px obrázek (aby na stránce nerušil):

<img src="akce.php">

Případně je možné pingnutí obrázkem provést v JavaScriptu (s generováním prázdného obrázku se nemusíme obtěžovat):

var obrazek = new Image();
obrazek.src = "akce.php";