1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
|
---
title: Primers passos
slug: Web/Guide/AJAX/Primers_passos
tags:
- AJAX
- Totes_les_categories
translation_of: Web/Guide/AJAX/Getting_Started
---
<p>
Aquest article us guiarà a través dels principis bàsics d'AJAX i amb dos pràctics exemples per a anar per feina.
</p>
<h3 id="Qu.C3.A8_.C3.A9s_l.27AJAX.3F" name="Qu.C3.A8_.C3.A9s_l.27AJAX.3F"> Què és l'AJAX? </h3>
<p>El <b>JavaScript asincrònic i XML</b>, (<i>Asynchronous JavaScript and XML, <b>AJAX</b>, en anglès</i>) és un neologisme per a dues potents característiques de navegació que fa anys que existeixen, però que han estat ignorades per molts desenvolupadors web fins a la recent arribada d'aplicacions com Gmail, Google suggest o Google Maps.
</p><p>Les dues característiques en qüestió són poder:
</p>
<ul><li> Fer sol·licituds al vostre servidor sense haver d'actualitzar la pàgina
</li><li> Analitzar i treballar amb documents XML
</li></ul>
<h3 id="Primer_pas_.E2.80.93_Com_fer_una_sol.C2.B7licitud_HTTP" name="Primer_pas_.E2.80.93_Com_fer_una_sol.C2.B7licitud_HTTP"> Primer pas – Com fer una sol·licitud HTTP </h3>
<p>Per a fer una sol·licitud HTTP (HTTP request) al servidor fent servir JavaScript, us cal una instància d'una classe que us en proporcioni la funcionalitat. Aquest tipus de classe va introduir-se originalment a l'Internet Explorer com a objecte ActiveX, anomenant-se <code>XMLHTTP</code>. Més endavant, Mozilla i Safari implementaren una classe, <code>XMLHttpRequest</code>, que funciona amb els mètodes i propietats de l'objecte original ActiveX de Microsoft.
</p><p>Com a resultat, per a crear una instància (objecte) de la classe perquè funcioni a tots els navegadors, heu de fer:
</p>
<pre>if (window.XMLHttpRequest) { // Mozilla, Safari, ...
sol·licitud_HTTP = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
sol·licitud_HTTP = new ActiveXObject("Microsoft.XMLHTTP");
}
</pre>
<p>(L'exemple anterior és una versió simplificada il·lustrativa del codi que s'utilitza per a crear una instància XMLHTTP. Per a un exemple del dia a dia, consulteu el tercer pas d'aquest article.)
</p><p>Algunes versions dels navegadors Mozilla no funcionaran correctament si la resposta del servidor no té una capçalera MIME XML. Per a satisfer aquesta exigència, podeu utilitzar una crida d'un mètode extra per a ignorar la capçalera que pogués enviar el servidor, si aquesta no fos <code>text/xml</code>.
</p>
<pre>sol·licitud_HTTP = new XMLHttpRequest();
sol·licitud_HTTP.overrideMimeType('text/xml');
</pre>
<p>Tot seguit, cal decidir què voleu fer després de rebre la resposta del servidor a la vostra sol·licitud. En aquest estadi, només cal que especifiqueu a l'objecte de sol·licitud HTTP quina funció de JavaScript processarà la resposta.
Això es fa definint la propietat <code>onreadystatechange</code> de l'objecte per al nom de la funció de JavaScript que penseu fer sevir, tal com es mostra a continuació:
</p><p><code>sol·licitud_HTTP.onreadystatechange = nom_de_la_funció;</code>
</p><p>Tingueu en compte que no hi ha parèntesis després del nom de la funció i no es passa cap paràmetre. A més, en comptes de donar un nom de funció, podeu utilitzar la tècnica de JavaScript de definir funcions al vol i les accions que en processaran la resposta, tal com es mostra a continuació: </p>
<pre>sol·licitud_HTTP.onreadystatechange = function(){
// fes el que calgui
};
</pre>
<p>Després d'haver declarat allò que passarà després de rebre la resposta, cal fer-ne la sol·licitud. Heu de cridar els mètodes <code>open()</code> i <code>send()</code> de la classe de sol·licitud HTTP, tal com es mostra a continuació:
</p>
<pre>sol·licitud_HTTP.open('GET', 'http://www.exemple.org/algun.fitxer', true);
sol·licitud_HTTP.send(null);
</pre>
<ul><li> El primer paràmetre de la crida a <code>open()</code> és el mètode de sol·licitud HTTP – GET, POST, HEAD o qualsevol altre mètode que ja vulgueu utilitzar i funcioni al vostre servidor. Escriviu-lo en majúscules atès que és un estàndard de l'HTTP; per altra banda, alguns navegadors (com el Firefox) podrien no processar la sol·licitud. Per a més informació dels mètodes de sol·licitud HTTP, podeu consultar les <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html" class="external">especificacions W3C</a> </li><li> El segon paràmetre és l'URL de la pàgina que esteu sol·licitant. Com a mesura de seguretat, no podeu cridar a pàgines en dominis de tercers. Assegureu-vos que utilitzeu el nom de domini exacte en totes les vostres pàgines o tindreu un error de «permís denegat» quan crideu a open(). Una trampa comuna és accedir al vostre lloc web amb domini.tld, però intentar cridar les pàgines amb www.domini.tld.
</li><li> El tercer paràmetre defineix si la sol·licitud és asincrònica. Si és així, <code>TRUE</code>, l'execució de la funció de JavaScript continuarà mentre la resposta del servidor no hagi arribat. Aquesta és l'A d'AJAX.
</li></ul>
<p>El paràmetre al mètode <code>send()</code> pot ser qualsevol dada que vulgueu enviar al servidor si s'envia la sol·licitud amb POST. Les dades cal que siguin de la forma d'una cadena de consulta com aquesta:
</p><p><code>nom=valor&un_altre_nom=un_altre_valor&i_així=anar_fent</code>
</p><p>Tingueu en compte que si voleu enviar dades amb POST, heu de canviar el tipus MIME de la sol·licitud utilitzant la següent línia:
</p>
<pre>sol·licitud_HTTP.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
</pre>
<p>Si no ho feu així, el servidor rebutjarà les dades que hi hàgiu enviat.
</p>
<h3 id="Segon_pas_.E2.80.93_Gestionar_la_resposta_del_servidor" name="Segon_pas_.E2.80.93_Gestionar_la_resposta_del_servidor"> Segon pas – Gestionar la resposta del servidor </h3>
<p>Recordeu que quan envieu la sol·licitud, també proporcioneu el nom de la funció JavaScript destinada a gestionar-ne la resposta.
</p><p><code>sol·licitud_HTTP.onreadystatechange = nom_de_la_funció;</code>
</p><p>Observem què hauria de fer aquesta funció. Primer, cal que comprovi l'estat de la sol·licitud. Si aquesta té el valor 4, vol dir que s'ha rebut una resposta total del servidor i podeu continuar processant-la. </p>
<pre>if (sol·licitud_HTTP.readyState == 4) {
// tot va bé, s'ha rebut la resposta
} else {
// encara no està preparada
}
</pre>
<p>La llista sencera de valors d'estat, <code>readyState</code>, és la següent:
</p>
<ul><li> 0 (sense inicialitzar)
</li><li> 1 (s'està carregant)
</li><li> 2 (carregat)
</li><li> 3 (interactiu)
</li><li> 4 (complerta)
</li></ul>
<p>(<a href="http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/readystate_1.asp" class="external">Font</a>)
</p><p>A continuació, cal que comproveu el codi d'estat de la resposta de servidor HTTP. Tots els codis possible es llisten al <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html" class="external">lloc del W3C</a>. Per als nostres objectius, només ens interessa la resposta <code>200 OK</code>.
</p>
<pre>if (sol·licitud_HTTP.status == 200) {
// perfecte!
} else {
// hi ha hagut algun problema amb la sol·licitud
// per exemple, la resposta podria ser uns codis de resposta
// 404 (Not Found) o 500 (Internal Server Error)
}
</pre>
<p>Després d'haver comprovat l'estat de la sol·licitud i el codi d'estat HTTP de la resposta, heu de decidir què voleu fer amb les dades que el servidor us ha enviat. Teniu dues opcions per a accedir a les dades:
</p>
<ul><li> <code>sol·licitud_HTTP.responseText</code> – retornarà la resposta del servidor com una cadena de text.
</li><li> <code>sol·licitud_HTTP.responseXML</code> – retornarà la resposta com un objecte document XML, <code>XMLDocument</code>, que podeu recórrer utilitzant les funcions DOM de JavaScript.
</li></ul>
<h3 id="Tercer_pas_.E2.80.93_Un_exemple_simple" name="Tercer_pas_.E2.80.93_Un_exemple_simple"> Tercer pas – Un exemple simple </h3>
<p>Posem-ho tot junt i fem una sol·licitud HTTP simple. El nostre codi JavaScript sol·licitarà un document HTML, <code>prova.html</code>, que conté el text «Açò és un text.» i llavors notificarà, <code>alert()</code>, els continguts del fitxer <code>prova.html</code>.
</p>
<pre><script type="text/javascript" language="javascript">
function fes_sol·licitud(url) {
var sol·licitud_HTTP = false;
if (window.XMLHttpRequest) { // Mozilla, Safari,...
sol·licitud_HTTP = new XMLHttpRequest();
if (sol·licitud_HTTP.overrideMimeType) {
sol·licitud_HTTP.overrideMimeType('text/xml');
// Vegeu la nota a sota
}
} else if (window.ActiveXObject) { // IE
try {
sol·licitud_HTTP = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
sol·licitud_HTTP = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
if (!sol·licitud_HTTP) {
alert('S\'abandona :( No es pot crear una instància d'XMLHTTP');
return false;
}
sol·licitud_HTTP.onreadystatechange = function() { notifica_continguts(sol·licitud_HTTP); };
sol·licitud_HTTP.open('GET', url, true);
sol·licitud_HTTP.send(null);
}
function notifica_continguts(sol·licitud_HTTP) {
if (sol·licitud_HTTP.readyState == 4) {
if (sol·licitud_HTTP.status == 200) {
alert(sol·licitud_HTTP.responseText);
} else {
alert('Hi ha hagut un problema amb la sol·licitud.');
}
}
}
</script>
<span
style="cursor: pointer; text-decoration: underline"
onclick="fes_sol·licitud('prova.html')">
Fes una sol·licitud
</span>
</pre>
<p><br>
En aquest exemple:
</p>
<ul><li> L'usuari fa un clic a l'enllaç «Fes una sol·licitud»;
</li><li> Açò crida a la funció <code>fes_sol·licitud()</code> amb un paràmetre – el nom <code>prova.html</code> d'un fitxer HTML en el mateix directori;
</li><li> Es fa la sol·licitud i llavors (<code>onreadystatechange</code>) l'execució es passa a <code>notifica_continguts()</code>;
</li><li> <code>notifica_continguts()</code> comprova si la resposta s'ha rebut, i si és correcta, llavors <code>alert()</code> notifica dels continguts al fitxer <code>prova.html</code>.
</li></ul>
<p>Podeu provar l'exemple <a href="http://www.w3clubs.com/mozdev/httprequest_test.html" class="external">ací</a> i veure el fitxer de prova <a href="http://www.w3clubs.com/mozdev/test.html" class="external">també ací</a>.
</p><p><b>Nota</b>: La línia <code>sol·licitud_HTTP.overrideMimeType('text/xml');</code> anterior donarà errors a la consola de Javascript al Firefox 1.5b tal com es documenta a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=311724" class=" link-https" rel="freelink">https://bugzilla.mozilla.org/show_bug.cgi?id=311724</a> si la pàgina que es crida per XMLHttpRequest no és un XML vàlid (p.ex., si és text net).
</p><p>Si obteniu un error de sintaxi (Syntax Error) o de mal format (Not Well Formed Error) en el navegador, i no esteu intentant carregar una pàgina XML per XMLHttpRequest, suprimiu aquesta línia del codi.
</p><p><b>Nota 2</b>: si envieu una sol·licitud a un codi que retorni XML, en comptes d'un fitxer XML estàtic, heu d'especificar-ne algunes capçaleres de resposta si la vostra pàgina ha de funcionar amb l'Internet Explorer a més d'amb el Mozilla. Si no hi definiu la capçalera, <code>Content-Type: application/xml</code>, l'IE llançarà un error de Javascript 'Object Expected' després de la línia des d'on intenteu accedir a un element XML. Si no hi definiu una capçalera, <code>Cache-Control: no-cache</code>, el navegador emmagatzemarà a la memòria cau la resposta i no tornarà mai a trametre la sol·licitud, fent llavors que la depuració sigui tot un repte.
</p><p><b>Nota 3</b>: si la variable sol·licitud_HTTP s'utilitza globalment, aquelles funcions «competidores» que cridin a fes_sol·licitud() poden anul·lar-se unes a les altres, provocant doncs una condició de cursa. En declarar sol·licitud_HTTP com una variable local a la funció i passar-la a la funció notifica_continguts() ho evita.
</p><p><b>Note 4</b>: Per a registrar la funció de resposta onreadystatechange, no podeu tenir cap argument:
</p>
<pre>sol·licitud_HTTP.onreadystatechange = function() { notifica_continguts(sol·licitud_HTTP); }; //1 (sol·licitud simultània)
sol·licitud_HTTP.onreadystatechange = notifica_continguts(sol·licitud_HTTP); //2 (no funciona)
sol·licitud_HTTP.onreadystatechange = notifica_continguts; //3 (variable global)
</pre>
<p>El mètode 1 us permet tenir diferent sol·licituds fetes simultàniament, el 2 no funciona, i el 3 s'utilitza si sol·licitud_HTTP és una variable global.
</p>
<h3 id="Quart_pas_.E2.80.93_Treballant_amb_la_resposta_XML" name="Quart_pas_.E2.80.93_Treballant_amb_la_resposta_XML"> Quart pas – Treballant amb la resposta XML </h3>
<p>En l'anterior exemple, després que es rebés la resposta a la sol·licitud HTTP, vam fer servir la propietat <code>reponseText</code> de l'objecte de sol·licitud i contenia els continguts del fitxer <code>prova.html</code>. Provem-ho ara amb la propietat <code>responseXML</code>.
</p><p>Comencem creant un document XML vàlid, que sol·licitarem més endavant. El document (prova.xml) conté el següent:
</p>
<pre><?xml version="1.0" ?>
<root>
Açò és una prova.
</root>
</pre>
<p>A la seqüència, només cal que canviar-hi la línia de sol·licitud per:
</p>
<pre>...
onclick="fes_sol·licitud('prova.xml')">
...
</pre>
<p>Llavors a <code>notifica_continguts()</code> cal que reemplacem la línia amb <code>alert()</code> d'<code>alert(sol·licitud_HTTP.responseText);</code> per:
</p>
<pre>var document_xml = sol·licitud_HTTP.responseXML;
var node_arrel = document_xml.getElementsByTagName('root').item(0);
alert(node_arrel.firstChild.data);
</pre>
<p>D'aquesta forma prenem l'objecte <code>XMLDocument</code> donat per <code>responseXML</code> i utilitzem els mètodes DOM per a accedir a algunes dades que es troben al document XML. Podeu veure-ho a <code>prova.xml</code> <a href="http://www.w3clubs.com/mozdev/test.xml" class="external">ací</a> i la seqüència de prova actualizada <a href="http://www.w3clubs.com/mozdev/httprequest_test_xml.html" class="external">ací</a>.
</p><p>Per a més informació dels mètodes DOM, consulteu els documents de la <a href="http://www.mozilla.org/docs/dom/" class="external">implementació DOM de Mozilla</a>.
</p>{{ languages( { "de": "de/AJAX/Getting_Started", "en": "en/AJAX/Getting_Started", "es": "es/AJAX/Primeros_Pasos", "fr": "fr/AJAX/Premiers_pas", "ja": "ja/AJAX/Getting_Started", "pl": "pl/AJAX/Na_pocz\u0105tek", "pt": "pt/AJAX/Como_come\u00e7ar" } ) }}
|