Compare Revisions

AJAX/Jak_začít

Revision 260864:

Revision 260864 by DJ.Maca on

Revision 229556:

Revision 229556 by DJ.Maca on

Title:
AJAX/Jak_začít
Jak začít
Slug:
AJAX/Jak_začít
AJAX/Jak_začít
Tags:
AJAX, Všechny_kategorie
Content:

Revision 260864
Revision 229556
t7    <p>t
8      Tento článek vás provede základy AJAXu a dá vám d začátku d
>va jednoduché praktické příklady. 
9    </p>
10    <h3 id="Co_je_to_AJAX.3F" name="Co_je_to_AJAX.3F">
11      Co je to AJAX?
12    </h3>
13    <p>
14      <b>Asynchronní JavaScript a XML</b> (angl. Asynchronous Jav
>aScript and XML, zkr. <b>AJAX</b>) je nově vytvořený termín pro d 
>vě mocné vlastnosti webových prohlížečů. Byly k dispozici léta, a 
>le až doposud byly mnoha webovými vývojáři přehlíženy, než se sta 
>ly hitem aplikace typu <a class="external" href="http://gmail.goo 
>gle.com">Gmail</a>, <a class="external" href="http://labs.google. 
>com/suggestfaq.html">Google Suggest</a> a <a class="external" hre 
>f="http://maps.google.com">Google Maps</a>. 
15    </p>
16    <p>
17      Zmíněné dvě vlastnosti jsou tyto:
18    </p>
19    <ul>
20      <li>zasílání žádostí na server bez nutnosti znovu-načtení s
>tránky 
21      </li>
22      <li>zpracovávání XML dokumentů
23      </li>
24    </ul>
25    <h3 id="Krok_1_.E2.80.93_.C5.99.C3.ADct_.22Pros.C3.ADm.21.22_
>aneb_jak_vytvo.C5.99it_HTTP_po.C5.BEadavek" name="Krok_1_.E2.80.9 
>3_.C5.99.C3.ADct_.22Pros.C3.ADm.21.22_aneb_jak_vytvo.C5.99it_HTTP 
>_po.C5.BEadavek"> 
26      Krok 1 – říct "Prosím!" aneb jak vytvořit HTTP požadavek
27    </h3>
28    <p>
29      K vytvoření HTTP požadavku na server použitím JavaScriptu p
>otřebujete instanci třídy, která tuto funkcionalitu poskytuje. Ta 
>ková třída byla původně představena v Internet Exploreru jako obj 
>ekt ActiveX zvaný <code>XMLHTTP</code>. Prohlížeče Mozilla, Safar 
>i a další následně začlenily třídu <code>XMLHttpRequest</code>, k 
>terá podporuje metody a vlastnosti původního objektu ActiveX od M 
>icrosoftu. 
30    </p>
31    <p>
32      Instanci (objekt) požadované třídy vytvoříte takto:
33    </p>
34    <pre>
35if (window.XMLHttpRequest) { // Mozilla, Safari, Opera, Konqueror
>, ... 
36    http_zadost = new XMLHttpRequest();
37} else if (window.ActiveXObject) { // Internet Explorer
38    http_zadost = new ActiveXObject("Microsoft.XMLHTTP");
39}
40</pre>
41    <p>
42      (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 živ 
>ota naleznete ve třetím kroku tohoto článku.) 
43    </p>
44    <p>
45      Některé verze prohlížeče Mozilla nebudou pracovat správně, 
>pokud odpověď ze serveru nemá hlavičku XML <code>mime-type</code> 
>. Potřebujete-li toto obejít, můžete použít zvláštní volání metod 
>y k potlačení hlavičky odeslané serverem v případě, že není <code 
>>text/xml</code>. 
46    </p>
47    <pre>
48http_zadost = new XMLHttpRequest();
49http_zadost.overrideMimeType('text/xml');
50</pre>
51    <p>
52      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 <code>onreadystatechange</co 
>de> objektu na jméno JavaScriptové funkce, kterou se chystáte pou 
>žít, např.: 
53    </p>
54    <p>
55      <code>http_zadost.onreadystatechange = jmenoFunkce;</code>
56    </p>
57    <p>
58      Všimněte si, že za jménem funkce nestojí žádné parametry an
>i 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 JavaScript 
>ovou techniku, definující funkci za běhu (tzv. "anonymní funkce") 
>, a definovat události, které budou zpracovávat odpověď přímo, ta 
>kto: 
59    </p>
60    <pre>
61http_zadost.onreadystatechange = function(){
62    // udělej něco
63};
64</pre>
65    <p>
66      Poté, co se rozhodnete, jak zpracovávat odpovědi, potřebuje
>te vytvořit opravdovou žádost a tedy zavolat metody <code>open()< 
>/code> a <code>send()</code> na třídu HTTP žádosti, např. takto: 
67    </p>
68    <pre>
69http_zadost.open('GET', 'http://www.example.org/nejaky.soubor', t
>rue); 
70http_zadost.send(null);
71</pre>
72    <ul>
73      <li>První parametr volající <code>open()</code> je metoda H
>TTP žádosti - <code>GET</code>, <code>POST</code>, <code>HEAD</co 
>de> č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 <a  
>class="external" href="http://www.w3.org/Protocols/rfc2616/rfc261 
>6-sec9.html">specifikaci na W3C</a> 
74      </li>
75      <li>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í st 
>rany. 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 <code>open()</code> do 
>jí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 j 
>ako <tt>www.domena.tld</tt>. 
76      </li>
77      <li>Třetí parametr nastavuje, je-li žádost asynchronní. Pok
>ud je nastavena na <code>true</code>, JavaScriptová funkce pokrač 
>uje, zatímco odpověď od serveru ještě nebyla. Proto to první "A"  
>ve slově "AJAX". 
78      </li>
79    </ul>
80    <p>
81      Parametr metody <code>send()</code> může obsahovat jakákoli
>v data, která chcete odeslat v žádosti na server přes <code>POST< 
>/code>. Data dotazu by měla být ve tvaru řetězce, např. takto: 
82    </p>
83    <p>
84      <code>jmeno=hodnota&amp;jinejmeno=dalsihodnota&amp;so=on</c
>ode> 
85    </p>
86    <p>
87      Povšimněte si, že pokud chcete poslat data přes <code>POST<
>/code>, musíte změnit MIME typ žádosti: 
88    </p>
89    <pre>
90http_zadost.setRequestHeader('Content-Type', 'application/x-www-f
>orm-urlencoded'); 
91</pre>
92    <p>
93      Server jinak zahodí data tímto způsobem odeslaná.
94    </p>
95    <h3 id="Krok_2_.E2.80.93_.22Jdeme_na_to.21.22_aneb_obsluha_od
>pov.C4.9Bdi_ze_serveru" name="Krok_2_.E2.80.93_.22Jdeme_na_to.21. 
>22_aneb_obsluha_odpov.C4.9Bdi_ze_serveru"> 
96      Krok 2 – "Jdeme na to!" aneb obsluha odpovědi ze serveru
97    </h3>
98    <p>
99      Vzpomeňte si, že když jste posílali svou žádost, uváděli js
>te jméno funkce, která slouží ke zpracování odpovědi: 
100    </p>
101    <p>
102      <code>http_zadost.onreadystatechange = jmenoFunkce;</code>
103    </p>
104    <p>
105      Podívejme se, co by taková funkce měla dělat. Zaprvé, funkc
>e potřebuje zkontrolovat stav žádosti. Pokud má stav hodnotu 4, z 
>načí to, že byla přijata kompletní odpověď ze serveru a vy ji můž 
>ete v pořádku zpracovat. 
106    </p>
107    <pre>
108if (http_zadost.readyState == 4) {
109    // Vše je v pořádku, odpověď byla přijata
110} else {
111    // Ještě nejsem připravený
112}
113</pre>
114    <p>
115      Úplný seznam hodnot <code>readyState</code> je následující:
116    </p>
117    <ul>
118      <li>0 (neinicializováno)
119      </li>
120      <li>1 (nahrávání)
121      </li>
122      <li>2 (nahráno)
123      </li>
124      <li>3 (zpracovávano)
125      </li>
126      <li>4 (hotovo)
127      </li>
128    </ul>
129    <p>
130      (<a class="external" href="http://msdn.microsoft.com/worksh
>op/author/dhtml/reference/properties/readystate_1.asp">Zdroj</a>) 
131    </p>
132    <p>
133      Další věc ke kontrole je stavový kód z odpovědi HTTP server
>u. Všechny možné kódy jsou uvedené na <a class="external" href="h 
>ttp://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">webu W3C</ 
>a>. Pro naše účely jsme se zajímali pouze o odpověď <code>200 OK< 
>/code>. 
134    </p>
135    <pre>
136if (http_zadost.status == 200) {
137    // Perfektní!
138} else {
139    // Byl problém s dotazem, 
140    // například kód odpovědi byl možná 404 (Stránka nenalezena)
141    // nebo 500 (Interní chyba serveru)
142}
143</pre>
144    <p>
145      Poté, co zkontrolujete stav žádosti a stavový kód HTTP odpo
>vě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: 
146    </p>
147    <ul>
148      <li>
149        <code>http_zadost.responseText</code> – odpověď serveru j
>ako textový řetězec. 
150      </li>
151      <li>
152        <code>http_zadost.responseXML</code> – odpověď serveru ja
>ko <code>XMLDocument</code> objekt, který můžete procházet pomocí 
> DOM funkcí v JavaScriptu 
153      </li>
154    </ul>
155    <h3 id="Krok_3_.E2.80.93_.22Te.C4.8F_v.C5.A1e_dohromady.21.22
>_-_jednoduch.C3.BD_p.C5.99.C3.ADklad" name="Krok_3_.E2.80.93_.22T 
>e.C4.8F_v.C5.A1e_dohromady.21.22_-_jednoduch.C3.BD_p.C5.99.C3.ADk 
>lad"> 
156      Krok 3 – "Teď vše dohromady!" - jednoduchý příklad
157    </h3>
158    <p>
159      Dejme to vše dohromady a udělejme jednoduchou HTTP žádost. 
>Náš JavaScript zažádá o HTML dokument <code>test.html</code>, kte 
>rý obsahuje text "Jsem test!". Obsah tohoto souboru následně zobr 
>azíme v JavaScriptovém upozornění. 
160    </p>
161    <pre>
162&lt;script type="text/javascript" language="javascript"&gt;
163    function vytvoritZadost (url) {
164        var http_zadost = false;
165 
166        if (window.XMLHttpRequest) { // Mozilla, Safari, Opera, K
>onqueror... 
167            http_zadost = new XMLHttpRequest();
168            if (http_zadost.overrideMimeType) {
169                http_zadost.overrideMimeType('text/xml');
170                // Podívejte na poznámku o tomto řádku níže
171            }
172        } else if (window.ActiveXObject) { // Internet Explorer
173            try {
174                http_zadost = new ActiveXObject("Msxml2.XMLHTTP")
>; 
175            } catch (e) {
176                try {
177                    http_zadost = new ActiveXObject("Microsoft.XM
>LHTTP"); 
178                } catch (e) {}
179            }
180        }
181 
182        if (!http_zadost) {
183            alert('Giving up :( Nemohu vytvořit XMLHTTP instanci'
>); 
184            return false;
185        }
186        http_zadost.onreadystatechange = function() { stavObsahu(
>http_zadost); }; 
187        http_zadost.open('GET', url, true);
188        http_zadost.send(null);
189 
190    }
191 
192    function stavObsahu(http_zadost) {
193 
194        if (http_zadost.readyState == 4) {
195            if (http_zadost.status == 200) {
196                alert(http_zadost.responseText);
197            } else {
198                alert('Byl problém se žádostí.');
199            }
200        }
201 
202    }
203&lt;/script&gt;
204&lt;span
205    style="cursor: pointer; text-decoration: underline"
206    onclick="vytvoritZadost('test.html')"&gt;
207        Vytvořit žádost
208&lt;/span&gt;
209</pre>
210    <p>
211      <br>
212      V tomto příkladu:
213    </p>
214    <ul>
215      <li>Uživatel klikne na odkaz "Vytvořit žádost" ve webovém p
>rohlížeči. 
216      </li>
217      <li>Zavolá funkci <code>vytvoritZadost()</code> s parametre
>m – jméno HTML souboru <code>test.html</code>, uloženého ve stejn 
>ém adresáři jako volající skript. 
218      </li>
219      <li>Vytvoří se požadavek, řízení je předáno funkci <code>st
>avObsahu()</code> 
220      </li>
221      <li>
222        <code>stavObsahu()</code> zkontroluje, byla-li žádost při
>jata. Pokud je vše pořádku, obsah souboru se objeví na obrazovce  
>v upozornění JavaScriptu. 
223      </li>
224    </ul>
225    <p>
226      Příklad je k dispozici <a class="external" href="http://www
>.w3clubs.com/mozdev/httprequest_test.html">zde</a> vč. zdrojového 
> souboru <code>test.html</code> <a class="external" href="http:// 
>www.w3clubs.com/mozdev/test.html">zde</a>. 
227    </p>
228    <div class="note">
229      <p>
230        <b>Poznámka 1</b>: Výše uvedený řádek <code>http_zadost.o
>verrideMimeType('text/xml');</code> způsobí chybu v JavaScriptové 
> konzole ve Firefoxu 1.5 a pozdějším, jak je zdokumentováno na <a 
> class=" link-https" href="https://bugzilla.mozilla.org/show_bug. 
>cgi?id=311724" rel="freelink">https://bugzilla.mozilla.org/show_b 
>ug.cgi?id=311724</a> , pokud stránka volaná XMLHttpRequest není v 
>alidní XML (např. prostý text). To je vlastně správné chování; te 
>nto článek bude brzy upraven, aby tuto změnu reflektoval. 
231      </p>
232    </div>
233    <div class="note">
234      <p>
235        <b>Poznámka 2</b>: Pokud posíláte požadavek na části kódu
>, která vrátí XML, spíše než na statický XML soubor, musíte nasta 
>vit některé hlavičky odpovědi, pokud má vaše stránka pracovat kro 
>mě Mozilly i v Internet Exploreru. Pokud nenastavíte hlavičku <co 
>de>Content-Type: application/xml</code>, IE vrátí chybu JavaScrip 
>tu 'Očekáván objekt' po řádce, kde se snažíte přistupovat k XML e 
>lementům. Pokud nenastavíte hlavičku <code>Cache-Control: no-cach 
>e</code>, prohlížeč uloží odpověď ve vyrovnávací paměti a znovu n 
>eodešle další požadavky, což stíží ladění. 
236      </p>
237    </div>
238    <div class="note">
239      <p>
240        <b>Poznámka 3</b>: Pokud je proměnná <code>http_zadost</c
>ode> používána globálně, souběžná volání funkce <code>vytvoritZad 
>ost()</code> se mohou navzájem potlačit, což způsobí souběh. Dekl 
>arování proměnné <code>http_zadost</code> lokálně dané funkci a j 
>ejí předání funkci souběhu <code>stavObsahu()</code> zabrání. 
241      </p>
242    </div>
243    <div class="note">
244      <p>
245        <b>Poznámka 4</b>: K zaregistrování funkce, předávané <co
>de>onreadystatechange</code>, nemůžete použít žádné argumenty. Pr 
>oto následující kód není funkční: 
246      </p>
247      <pre>
248http_request.onreadystatechange = stavObsahu(http_zadost); // (ne
>funguje) 
249</pre>
250      <p>
251        Abyste úspěšně funkci zaregistrovali, můžete buď předat a
>rgumenty nepřímo prostřednictvím anonymní funkce, nebo použít <co 
>de>http_request</code> jako globální proměnnou. Následují příklad 
>y: 
252      </p>
253      <pre>
254http_zadost.onreadystatechange = function() { stavObsahu(http_zad
>ost); };  //1 (simulace žádosti) 
255http_zadost.onreadystatechange = stavObsahu;                     
>          //2 (globální proměnná) 
256</pre>
257      <p>
258        Metoda 1 vám umožňuje zpracovat několik požadavků současn
>ě, zatímco metoda 2 se používá, když <code>http_zadost</code> je  
>globální proměnná. 
259      </p>
260    </div>
261    <div class="note">
262      <p>
263        <b>Poznámka 5</b>: V případě komunikační chyby (jako výpa
>dek webového serveru), bude vrácena výjimka v metodě onreadystate 
>change při pokusu o přistup k proměnné <code>.status</code>. Ujis 
>těte se, že takovou výjimku zpracováváte. (Viz. <a class=" link-h 
>ttps" href="https://bugzilla.mozilla.org/show_bug.cgi?id=238559"  
>rel="freelink">https://bugzilla.mozilla.org/show_bug.cgi?id=23855 
>9</a>). 
264      </p>
265    </div>
266    <pre>
267function stavObsahu(http_zadost) {
268 
269        try {
270            if (http_zadost.readyState == 4) {
271                if (http_zadost.status == 200) {
272                    alert(http_zadost.responseText);
273                } else {
274                    alert('Byl problém se žádostí.');
275                }
276            }
277        }
278        catch( e ) {
279            alert('Zachycená výjimka: ' + e.description);
280        }
281 
282    }
283</pre>
284    <h3 id="Krok_4_.E2.80.93_.22Akta_X.22_aneb_pr.C3.A1ce_s_XML_o
>dpov.C4.9Bd.C3.AD" name="Krok_4_.E2.80.93_.22Akta_X.22_aneb_pr.C3 
>.A1ce_s_XML_odpov.C4.9Bd.C3.AD"> 
285      Krok 4 – "Akta X" aneb práce s XML odpovědí
286    </h3>
287    <p>
288      V předešlém příkladě jsme použili pro přijetí odpovědi na H
>TTP žádost vlastnost <code>responseText</code> objektu odpovědi,  
>která obsahovala obsah souboru <tt>test.html</tt>. Nyní si to zku 
>síme pomocí vlastnosti <code>responseXML</code>. 
289    </p>
290    <p>
291      Nejprve si vytvoříme validní XML dokument, který později vy
>žádáme. Dokument (<tt>test.xml</tt>) obsahuje následující: 
292    </p>
293    <pre>
294&lt;?xml version="1.0" ?&gt;
295&lt;root&gt;
296    Jsem test!
297&lt;/root&gt;
298</pre>
299    <p>
300      Ve skriptu potřebujeme pouze změnit řádek se žádostí:
301    </p>
302    <pre>
303...
304onclick="vytvoritZadost('test.xml')"&gt;
305...
306</pre>
307    <p>
308      Pak v <code>stavObsahu()</code> potřebujeme nahradit řádek 
>s <code>alert(http_zadost.responseText);</code> na: 
309    </p>
310    <pre>
311var xmldoc = http_zadost.responseXML;
312var koren_uzlu = xmldoc.getElementsByTagName('root').item(0);
313alert(koren_uzlu.firstChild.data);
314</pre>
315    <p>
316      Tento kód přijme objekt <code>XMLDocument</code>, předaný p
>omocí <code>responseXML</code>, 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> <a class="external" href="http://www.w3clubs.com 
>/mozdev/test.xml">zde</a> a upravený testovací skript <a class="e 
>xternal" href="http://www.w3clubs.com/mozdev/httprequest_test_xml 
>.html">zde</a>. 
317    </p>
318    <p>
319      Více o DOM metodách naleznete v dokumentaci o <a class="ext
>ernal" href="http://www.mozilla.org/docs/dom/">implementaci DOM v 
> Mozille</a>. 
320    </p>{{ languages( { "en": "en/AJAX/Getting_Started", "ca": "c
>a/AJAX/Primers_passos", "de": "de/AJAX/Getting_Started", "es": "e 
>s/AJAX/Primeros_Pasos", "fr": "fr/AJAX/Premiers_pas", "ja": "ja/A 
>JAX/Getting_Started", "pl": "pl/AJAX/Na_pocz\u0105tek", "pt": "pt 
>/AJAX/Como_come\u00e7ar" } ) }} 

Back to History