3. díl - JSONP pro začátečníky

JavaScript AJAX JSONP pro začátečníky

Úvod:

Většina JavaScript programátorů dobře zná formát dat JSON - víte, že JSON je vlastně String, objekt, a že to může být také soubor. Tyto informace jsou rozhodně zajímavé, určitě vám pomůžou v pochopení jak technika, kterou dnes budu popisovat, dostala svůj název. Pro případ, že si nejste problematikou JSONu úplně jistí, můžete, ale nemusíte vyhledat dokumentaci na internetu - nebudete ji nijak zvlášť potřebovat.

Význam:

Co tedy to JSONP vlastně znamená? JavaScript Object Notation with Padding/Prefix - jinými slovy je JSON formát dat a to 'P' navíc říká, že technika, která je takto označována, má co do činění s JSONem, ale přináší si nějaké vlastnosti navíc.

Co JSONP umí a k čemu slouží? Slyšeli jste o AJAXu a jeho schopnosti zpracovávat background požadavky na server. Jistě také víte, že se AJAX musí řídit SOP (Same Origin Policy), která mu zakazuje volat serverové API na jiném portu, či jiné doméně, než je samotný web/aplikace umístěna. To je značně omezující, například nemůžeme AJAXem zavolat na webové API s aktuálním počasím na cizím portálu a zobrazit výsledek našemu uživateli.

Představme si, že nemáme jinou možnost, než tuto restrikci obejít. Přístup do PHP zdrojáků nám nebyl umožněn a my si musíme vystačit s tím co dá JavaScript. Cestou je samozřejmě právě JSONP technika, o které je dnešní díl seriálu.

Jak to funguje?

Tato technika je založená na HTML tagu 'script' a faktu, že když stahujete JavaScript zdroják a načítáte ho do stránky, nemusí být tento soubor umístěn na vašem webu. Při jeho stažení tedy nedojde k porušení SOP. Za běhu vezmeme URL API, na které budeme volat, vytvoříme si element typu 'script' a nastavíme mu atribut url na naše URL zmíněné výše. Tento element pak už jen umístíme do HTML dokumentu. V ten moment browser zareaguje a provede standardní operace pro takovýto element, například zavolá URL z atributu a pokusí se pomocí metody GET získat zpět data. Výhodou je, že toto volání je asynchronní stejně jako AJAXový request.

Jak už sami pomalu rozeznáváte, spíš než přirovnávat JSONP k AJAXu, je vhodné vidět v něm klasický 'script' tag a defaultní akce prohlížeče. Představte si, že stahujete knihovnu jQuery z online uložiště (CDN), pomocí script tagu o ní požádáte server, ten vám vrátí soubor a prohlížeč ho načte, zkontroluje a zpracuje. Kontrola je důležitý krok. Tato kontrola formátu totiž ověřuje, jestli se skutečně jedná o JavaScript zdroják se všemi náležitostmi, v opačném případě dojde k chybě a snaha o JSONP selže. Co tedy můžeme poslat ze serveru klientovi, tak aby to fungovalo?

Můžeme poslat script jak má být – jen proměnné se kterými se třeba ihned potom začne pracovat, nebo celé knihovny funkcí. Pokud toto děláme, dá se říci, že vlastně stavíme celou webovou aplikaci za běhu. Doslova zasouváme proměnné, objekty a funkce do kontextu v průběhu provádění scriptu. Máme ale i jinou možnost. V našem JavaScriptu, který se stáhne se stránkou už od začátku, napíšeme funkci nesoucí jméno třeba 'serverDataRe­ciever'. Tato funkce bude obsahovat základní příkazy pro práci s daty, která přijdou například ze serveru o počasí. Když potom provedeme volání na server, nezapomeneme k atributu 'url' tagu 'script' připojit string "?callback=ser­verDataReciever". Jak už jsem řekl, pro získávání scriptů ze serverů používá browser metodu GET. Důležité je, že používá pouze ji a žádnou jinou. Server pak obdrží 'callback' parametr a ví, jak se jmenuje funkce, kterou chceme na klientovi volat jako callback. Výsledné echo potom vypadá asi takto: (v PHP)

echo $_GET["callback"] . "(" . $dataProKlienta . ");";

Z tohoto příkladu už je celkem patrné, o co vlastně jde. Podobná technika se dnes v JavaScriptu běžně používá, tedy volání funkce, předání dat a předání callbacku, který obdrží výsledná data z první funkce a na konci je jí zavolán. V našem případě se sestaví JavaScript 'zdroják', ve skutečnosti to budou pouze data předávaná jako parametr callbackové funkci a volání oné funkce, ale v JavaScriptu můžeme jako parametr použít expressions, což nám dává značné možnosti. Ze všech případů vyberu ty nejobvyklejší:

nejakaFunkce(23, "textovy retezec", 2 > 0 ? "ternarni" : "operator", (function(data) {return data * 23})(window.data), Kolekce.get(4));

Jak to celé vypadá?

Ukážu a popíšu (pomocí komentářů) zdrojové kódy pro server i pro klienta.

HTML:

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
</head>
<body>
<script type="text/javascript">
        function callTheJsonp() {
                // adresa serveru, na který voláme asynchronní požadavek
                var url = "jsonp.php?callback=recieveResponse";
                // vytvořím nový element script
                var script = document.createElement('script');
                // nastavím mu odpovídající adresu
                script.setAttribute('src', url);
                // a nakonec vložím element do stránky
                document.getElementsByTagName('head')[0].appendChild(script);
        }

        // tato funkce bude zavolána klientem na příkaz serveru a parametrem jí budou data ze serveru, ta data, o která jsme žádali, mohou být ve formátu JSON, XML, text, js, atd.
        function recieveResponse(response) {
                console.log(response);
        }
</script>
<span onclick="callTheJsonp()">Klikni, pro JSONP požadavek!</span>
</body>
</html>

PHP:

<?php
// získám jméno callback funkce
$callback = '';
if (isset($_GET['callback'])) {
        $callback = filter_var($_GET['callback'], FILTER_SANITIZE_STRING);
        }else {
        // pokud ho nezískám, použiju consoli
        $callback = "console.log";
        // echnu celý javascript jako textový řetězec
        echo $callback . "(" . "Klasický text." . ");";
?>

Motivace?

Nebývá obvyklé uvádět motivaci na závěr, nicméně toto není motivace k článku, ale k vašemu vlastnímu tvoření. Představte si, co všechno máte možnost díky tomuto udělat. Můžete kupříkladu doslova stavit "vzdušné zámky" uživateli pod rukama, pokud máte aplikaci, která se má (po javascriptové stránce) pokaždé chovat trochu jinak - stačí na začátek ověřit podmínky a stáhnout tu správnou knihovnu. Také můžete dostahovávat scripty pro události až v momentě, kdy se uživatel prokliká do určité části aplikace, což se může hodit pro OnePage aplikace, netvrdím ale, že bych to tak dělal.

Pravda je ale taková, že se JSONP nepoužívá, pokud to není opravdu nutné - jde o nestandardní techniku a navíc jí musí podporovat server. V zásadě tak můžete narazit na JSONP v rámci nějakého hacku nebo hotfixu, netvrdím ale, že je špatně, když se ve vašem zdrojáku objeví - vše záleží na okolnostech.

Závěr:

Pokud se na cokoliv z této problematiky chcete zeptat, neváhejte. V jednom z chystaných dílů nás čeká i použití JSONP pomocí knihovny jQuery. A můžete se těšit i na popis nejznámějších způsobů volání, nebo seznámení s formáty dat, které se pro tento účel používají.


 

  Aktivity (3)

Článek pro vás napsal Taskkill
Avatar
Autor se věnuje vývoji na mobilních platformách a webu. Zajímá se o všechny oblasti informačních technologií a je zapřísáhlým fanouškem Open Source. Hrdě používá OS GNU Debian a všechno co je freeware.

Jak se ti líbí článek?
Celkem (4 hlasů) :
4.254.254.254.25 4.25


 


Miniatura
Předchozí článek
Metody GET a POST v AJAXu
Miniatura
Všechny články v sekci
AJAX

 

 

Komentáře

Avatar
Michal Žůrek (misaz):

Podle mě to vysvětluješ moc komplikovaně, ale ukázka pak mluví za vše.

Odpovědět  +1 3.10.2015 23:21
Nesnáším {}, proto se jim vyhýbám.
Avatar
Taskkill
Redaktor
Avatar
Odpovídá na Michal Žůrek (misaz)
Taskkill:

Na stylu výkladu hodně pracuju (vím o svých slabinách už delší dobu, jen mi dělá problém se právě s tou komplikovaností vypořádat) ... snažím se podat informace v co nejucelenější podobě ... vím, že by někdo mohl říct, že by stačilo prostě popsat jak to funguje, já se ale znažím vždycky doplnit výklad souvislostmi, aby čtenář mohl další studium odstartovat o to snadněji. Nicméně jsem autor-začátečník, zkrátka musíme být všichni trpěliví.

 
Odpovědět 4.10.2015 13:05
Avatar
Odpovídá na Taskkill
Michal Žůrek (misaz):

spíš jde o to že bych do toho úvodu moc netahal AJAX a tak. Ono mi přijde jednoduší se na to dívat, že tak jak načítáš dynamicky za běhu obrázky (tag IMG), tak můžeš za běhu načítat script (tag SCRIPT). Myslím že tou větou jsem tak velmi zjednodušeně se pokusil vysvětlit princip na kterém pak všechno ostatní (z této problematiky) staví.

Odpovědět 4.10.2015 18:42
Nesnáším {}, proto se jim vyhýbám.
Avatar
Taskkill
Redaktor
Avatar
Odpovídá na Michal Žůrek (misaz)
Taskkill:

Ovšem, to je úplná pravda, ale faktem je, že nejen mě šlo o to uvědomit čtenáře o faktu, že se to dá použít jako cross site ajax. V zásadě jsem to chtěl navléknout tak, aby si každý představil možnosti, které to nabízí.

 
Odpovědět 4.10.2015 21:58
Avatar
Marek Pech
Člen
Avatar
Marek Pech:

super :)

 
Odpovědět 5.10.2015 11:22
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 5 zpráv z 5.