FAQ JavaScriptConsultez toutes les FAQ
Nombre d'auteurs : 43, nombre de questions : 175, dernière mise à jour : 6 décembre 2013
- Qu'est ce que c'est qu'Ajax ?
- Quels sont les principaux avantages et inconvénients d'Ajax ?
- Quels sont les navigateurs compatibles avec XMLHttRequest ?
- Comment obtenir un objet XMLHttpRequest compatible avec tous les navigateurs ?
- XHR est asynchrone, qu'est ce que ça veux dire ?
- Que signifie l'erreur d'Internet Explorer : Erreur système : -1072896658 Code 0 ?
- Comment évaluer le contenu des balises script retourné par un appel Ajax?
- Qu'est ce que la notation JSON ?
- Comment mettre à jour un calque (div) avec un appel Ajax, en utilisant le framework Prototype ?
- Pourquoi mon xhr ne se met pas à jour (problème de cache) ?
- Pourquoi les événements disparaissent après une mise à jour avec AJAX ?
- Comment accéder à une page nécessitant une authentification ?
AJAX est un acronyme pour Asynchronous JavaScript And XML (JavaScript Asynchrone et XML). Il s'agit d'un concept inventé en 2004 et reposant sur des fondements bien plus anciens.
Le principe de base est d'intercepter en utilisant JavaScript les événements
survenant sur la page et d'y insérer dynamiquement un contenu
provenant d'un serveur Web, véhiculé par un document XML, toujours en utilisant
JavaScript.
La pierre angulaire de cette méthode est l'objet XMLHttpRequest() (parfois appelé XHR),
qui permet à JavaScript d'effectuer une requête vers le serveur sans que
l'utilisateur ne le voie, de façon asynchrone (en laissant la main à l'utilisateur).
Voici les principaux avantages et inconvénients généralement cités concernant l'utilisation d'AJAX.
Avantages
- Interactivité : les interfaces utilisant AJAX offrent une interactivité et une réactivité bien plus importantes que les pages habituelles, où l'utilisateur doit attendre le rechargement complet de sa page.
- Portabilité : tous les navigateurs actuels proposent l'ensemble des outils nécessaires à la mise en place d'un moteur AJAX.
Inconvénients
- Ergonomie : l'utilisation d'AJAX entraîne une impossibilité pour le visiteur d'utiliser son bouton "Retour" de façon attendue. De la même façon, AJAX pose des problèmes pour la mise en place de signets (bookmarks) sur les pages, ainsi que pour l'indexation du contenu des pages.
- Temps de latence : les appels vers le serveur peuvent avoir des temps de latence importants qui sont mal perçus et compris par les utilisateurs.
- Utilisation de JavaScript : le moteur AJAX fait fortement appel au JavaScript. Il faut prévoir pour les utilisateurs ayant désactivé JavaScript ou ne pouvant pas l'utiliser, une solution de repli acceptable.
- Complexité des développements : comme tout composant additionnel AJAX offre des possibilités, mais la mise en place peut se révéler coûteuse au moment du développement.
Les navigateurs qui prennent en charge l'objet XMLHttpRequest() sont :
- Konqueror 3.3
- Microsoft IE 5.5
- Mozilla 1.4
- Mozilla Firefox 0.8
- Netscape 7.1
- Opera 8.01
- Safari 1.2.1
Toutes les versions plus récentes de ces navigateurs supportent bien entendu également les objets XMLHttpRequest().
La méthode ci-dessous permet de retourner un objet XMLHttpRequest() dans tous les navigateurs supportant actuellement cet objet :
function
getXMLHTTP
(
){
var
xhr=
null
;
if
(
window.
XMLHttpRequest){
//
Firefox
et
autres
xhr =
new
XMLHttpRequest
(
);
}
else
if
(
window.
ActiveXObject){
//
Internet
Explorer
try
{
xhr =
new
ActiveXObject
(
"
Msxml2.XMLHTTP
"
);
}
catch
(
e) {
try
{
xhr =
new
ActiveXObject
(
"
Microsoft.XMLHTTP
"
);
}
catch
(
e1) {
xhr =
null
;
}
}
}
else
{
//
XMLHttpRequest
non
supporté
par
le
navigateur
alert
(
"
Votre
navigateur
ne
supporte
pas
les
objets
XMLHTTPRequest...
"
);
}
return
xhr;
}
L'objet XMLHttpRequest() est la plupart du temps utilisé en mode asynchrone (qui fait tout son intérêt).
En mode asynchrone, on donne l'adresse à laquelle l'objet XHR doit aller requêter (via la méthode open()) puis la réaction à avoir lorsque la requête reviendra (via la propriété onreadystatechange). Une fois XHR programmé de cette façon, on l'envoie par la méthode send().
À partir de là, telle une fusée dans l'espace, XHR part au loin et est en mode automatique. JavaScript nous rend la main (à l'utilisateur et/ou au script JavaScript) en sachant que XHR est correctement programmé.
Si on essaye d'accéder à la réponse associée à l'objet XMLHttpRequest()
tout de suite après l'avoir envoyé, celle-ci ne sera pas encore disponible.
De la même façon, si on réutilise ce même objet XHR dans un script suivant directement
le précédent, il y a fort à parier que celui-ci n'aura pas terminé sa requête.
En lui passant des nouveaux paramètres avec open(),
onreadystatechange
et send(),
on lui annule complètement sa mission précédente et on lui en redonne une autre.
Quelles sont les solutions ?
Pour l'accès à la réponse de l'objet XMLHttpRequest(), la seule et unique solution est d'accéder à ses propriétés ( responseText ou reponseXml) uniquement dans la méthode liée au onchange de l'objet XMLHtttpRequest().
Pour faire plusieurs requêtes, les solutions sont multiples:
- Se faire suivre les deux requêtes. Pour cela, il suffit d'indiquer à XHR qu'à son retour (onreadystatechange), il pourra directement repartir pour une autre mission.
- Effectuer les deux requêtes en parallèle. Pour cela, nous allons devoir créer deux instances de XMLHttpRequest() différentes (deux fusées), qui travailleront indépendamment.
- Réunir les deux requêtes. Généralement, si les deux requêtes se suivent systématiquement, il serait bien plus simple de n'effectuer qu'une seule requête vers le serveur, cette requête ramenant l'information nécessaire pour les deux actions.
- Dernière possibilité, certainement la plus mauvaise : utiliser XHR en mode synchrone. Dans ce cas, le navigateur sera bloqué tant que la requête ne sera pas revenue.
Il arrive parfois, lorsque l'on tente d'accéder à l'attribut responseText d'un
objet XMLHttpRequest() sous Internet Explorer, que celui-ci renvoie l'erreur
Erreur système : -1072896658 Code 0.
Ce texte d'erreur n'est pas d'une limpidité absolue, mais il signifie tout
simplement que le jeu de caractères (charset) utilisé par le serveur n'est pas
reconnu par Internet Explorer.
Assurez-vous d'avoir correctement placé le
header
dans le code que vous renvoyez :
Content-Type: text/plain; charset=UTF-8
Lorsqu'un appel AJAX retourne du contenu HTML contenant des scripts, ceux-ci ne sont pas évalués tout seuls si vous vous contentez de les insérer dans votre page. Il est nécessaire de les évaluer à la main.
var
mesScripts =
document.
getElementById
(
"
idDuDivDInsertion
"
).
getElementsByTagName
(
"
script
"
);
for
(
var
i=
0
;
i&
lt;
mesScripts.
length;
i+
+
) {
eval
(
mesScripts[
i]
.
innerHTML);
}
La notation JSON (JavaScript Object Notation) est un format permettant le passage des données à un programme JavaScript. Ce format est un des formats utilisés dans le cadre d'AJAX. Il présente l'avantage d'être plus léger que XML et d'être très facilement récupérable par le script JavaScript.
Il utilise la notation des objets de JavaScript, sous la forme :
var
objet =
{
"
propriété1
"
:
"
valeur1
"
,
"
propriété2
"
:
"
valeur2
"
}
objet a ainsi les attributs propriété1 et propriété2.
Cette notation peut également être utilisée pour les méthodes des objets :
var
objetAvecMethodesJSON =
{
"
disBonjour
"
:
function
(
) {
alert
(
'
bonjour
'
)}
,
"
propriété2
"
:
"
valeur2
"
}
;
L'objet peut être récupéré d'une requête AJAX au format habituel grâce à la méthode eval() :
var
objet =
eval
(
xhr.
responseText);
La sortie au format JSON est supportée nativement par PHP 5.2 et est implémentée par plusieurs bibliothèques Java, C# et dans la plupart des autres langages actuels.
Lien : Le site officiel de JSON
Le framework Prototype permet de simplifier fortement les appels AJAX.
Le code suivant va mettre dans l'élément ayant l'identifiant 'idDuDiv' le code HTML retourné par l'appel à la page adresseDeLaPage.php en transmettant le paramètre donné.
var
url =
'
adresseDeLaPage.php
'
;
var
pars =
'
param1=valeur1
'
;
var
target =
'
idDuDiv
'
;
var
myAjax =
new
Ajax.
Updater
(
target,
url,
{
method:
'
get
'
,
parameters:
pars}
);
Comment éviter que le navigateur ne réutilise le contenu mis en cache d'un fichier ?
1) Sur le serveur (ici en PHP, mais c'est adaptable)
<?php
header
("
Expires
:
Mon
,
26
Jul
1997
05
:
00
:
00
GMT
"
);
header
("
Last
-
Modified
:
"
.
gmdate
("
D
,
d
M
Y
H
:
i
:
s
"
) .
"
GMT
"
);
header
("
Cache
-
Control
:
no
-
store
,
no
-
cache
,
must
-
revalidate
"
);
header
("
Cache
-
Control
:
post
-
check
=
0
,
pre
-
check
=
0
"
,
false
);
header
("
Pragma
:
no
-
cache
"
);
?>
2) Depuis JavaScript (demander au navigateur de ne pas aller dans le cache)
a) Via
header
xhr_object.
setRequestHeader
(
"
Cache-Control
"
,
"
no-cache
"
);
b) Via Date
xhr_object.
open
(
.
.
.
,
url +
"
&date=
"
+
escape
(
new
Date
(
)),
.
.
.
);
Lorsque le navigateur charge une page HTML,
l'interpréteur JavaScript crée une collection d'objets HTMLElement.
Chaque balise correspondant à un objet spécifique.
Ainsi, quand on affecte un événement à une balise, celle-ci est référencée
par JavaScript comme une propriété de l'objet HTMLElement correspondant.
Donc, si vous mettez à jour votre page via AJAX
(et ce quelle que soit la méthode utilisée), vous détruisez les objets JavaScript
remplacés et leurs propriétés avec. Puis JavaScript va créer de nouveaux objets avec les balises HTML ajoutées.
Pour retrouver les propriétés des balises qui ont disparu, il faut tout simplement les réaffecter.
Il est donc important, lorsque l'on conçoit une page Web devant utiliser AJAX, de bien savoir à l'avance les éléments susceptibles d'être mis à jour. On prendra ensuite soin de créer des fonctions spécifiques d'affectation d'événements que l'on pourra ainsi facilement appeler après chaque mise à jour.
Par exemple, si l'on doit actualiser une <div> dont l'id est "ajax", on pourra regrouper l'affectation des événement pour les éléments qu'elle contient dans une fonction "afterAjax" et on codera :
.
.
.
xhr.
onreadystatechange =
function
(
){
if
(
xhr.
readyState =
=
4
&
&
xhr.
status =
=
200
){
document.
getElementById
(
'
ajax
'
).
innerHTML =
xhr.
responseText;
afterAjax
(
);
}
}
Il peut arriver que vous ayez besoin d'accéder par AJAX à une page Web nécessitant une authentification.
Pour y parvenir, deux méthodes peuvent être utilisées.
- Utiliser l'authentification par l'URL.
Le schéma général d'une URL permet d'envoyer les identifiants d'authentification entre le protocole et le domaine :
//
Si
le
login
est
toto
et
le
mot
de
passe
tata
//
La
fonction
getXHR()
renvoie
un
objet
XMLHttpRequest
valide
var
xhr =
getXHR
(
);
var
destURL =
'
http://toto:tata@www.monsite.com
'
;
xhr.
open
(
'
POST
'
,
destURL);
.
.
.
- En utilisant les paramètres de la méthode open().
Effectivement, les trois premiers paramètres de cette méthode sont largement connus, mais il est possible d'en passer deux supplémentaires qui correspondent au login et au mot de passe :
//
Si
le
login
est
toto
et
le
mot
de
passe
tata
//
La
fonction
getXHR()
renvoie
un
objet
XMLHttpRequest
valide
var
xhr =
getXHR
(
);
var
destURL =
'
http://www.monsite.com
'
;
xhr.
open
(
'
POST
'
,
destURL,
true
,
'
toto
'
,
'
tata
'
);
.
.
.
Si les deux méthodes sont combinées, ce sont les valeurs passées dans la méthode open() qui sont privilégiées.
Ces méthodes peuvent être utiles par exemple dans une interface d'administration, en revanche gardez bien à l'esprit que si les identifiants sont présents dans votre code, l'authentification devient douteuse : il n'existe aucun moyen de les protéger en JavaScript !