Créer des requêtes Ajax en utilisant l’objet XMLHttpRequest en JavaScript

L’objet XMLHttpRequest est un objet prédéfini, disponible dans tous les navigateurs et qui nous permet de faire des requêtes HTTP en JavaScript.

Dans cette partie, nous allons apprendre à envoyer et récupérer des données de manière asynchrone depuis un serveur, à suivre l’avancement de la tâche, etc.

 

Créer une première requête Ajax

Pour effectuer une requête asynchrone au serveur en utilisant l’objet XMLHttpRequest, nous allons toujours devoir suivre 4 étapes :

  1. On crée un objet XMLHttpRequest ;
  2. On initialise notre requête, c’est à dire on choisit le mode d’envoi des données, l’URL à demander, etc. ;
  3. On envoie la requête ;
  4. On crée des gestionnaires d’événements pour prendre en charge la réponse du serveur.

Pour créer un objet XMLHttpRequest, nous allons utiliser le constructeur XMLHttpRequest() avec la syntaxe classique new XMLHttpRequest().

Ensuite, pour initialiser notre requête, nous allons utiliser la méthode open() de XMLHttpRequest. On va pouvoir passer 2, 3, 4 ou 5 arguments à cette méthode :

Le premier argument (obligatoire) correspond au type de méthode de requête HTTP à utiliser. On va pouvoir choisir entre GET, POST, PUT, DELETE, etc. Dans la grande majorité des cas, on choisira GET ou POST.

Pour être tout à fait précis, on préférera GET pour des requêtes non destructives, c’est-à-dire pour effectuer des opérations de récupération simple de données sans modification tandis qu’on utilisera POST pour des requêtes destructives, c’est-à-dire des opérations durant lesquelles nous allons modifier des données sur le serveur ainsi que lorsqu’on souhaitera échanger des quantités importantes de données (POST n’est pas limitée sur la quantité de données, au contraire de GET).

Le deuxième argument (obligatoire) représente l’URL de destination de la requête, c’est-à-dire l’URL où on souhaite envoyer notre requête.

Le troisième argument (facultatif) est un booléen indiquant si la requête doit être faite de manière asynchrone ou pas. La valeur par défaut est true.

Les quatrième et cinquième arguments (facultatifs) permettent de préciser un nom d’utilisateur et un mot de passe dans un but d’authentification.

Une fois notre requête initialisée ou configurée grâce à open(), on va spécifier le format dans lequel le serveur doit nous renvoyer sa réponse en passant ce format en valeur de la propriété responseType de notre objet XMLHttpRequest. Les valeurs possibles sont les suivantes :

  • "" (chaine de caractères vide) : valeur par défaut; demande au serveur de renvoyer sa réponse sous forme de chaine de caractères ;
  • "text" : demande au serveur de renvoyer sa réponse sous forme de chaine de caractères ;
  • "arraybuffer" : demande au serveur de renvoyer sa réponse sous forme d’objet ArrayBuffer ;
  • "blob" : demande au serveur de renvoyer sa réponse sous forme d’objet Blob ;
  • "document" : demande au serveur de renvoyer sa réponse sous forme de document XML ;
  • "json" : demande au serveur de renvoyer sa réponse sous forme JSON.

Dans la majorité des cas, on demandera au serveur de nous renvoyer des données sous forme JSON (elles seront alors interprétées automatiquement) ou texte.

Une fois qu’on a défini le format de la réponse, nous allons pouvoir envoyer notre requête. Pour cela, nous allons utiliser la méthode send() de XMLHttpRequest.

Cette méthode ouvre la connexion avec le serveur et lui envoie la requête. On peut lui passer le corps de la requête en argument facultatif.

Support HTML pour création de requêtes Ajax en JavaScript avec XMLHttpRequest

Créer et envoyer des requêtes Ajax en utilisant l'objet XMLHttpRequest

 

Prendre en charge la réponse renvoyée par le serveur

Une fois notre requête envoyée, nous allons devoir réceptionner la réponse du serveur. Pour connaitre l’état d’avancement de notre requête, nous avons deux options.

Utiliser les gestionnaires d’événements load, error et progress

Nous allons pour cela utiliser des gestionnaires d’événements définis par l’interface XMLHttpRequestEventTarget qui vont nous permettre de prendre en charge différents événements déclenchés par notre requête et en particulier :

  • L’événement load qui se déclenche lorsque la requête a bien été effectuée et que le résultat est prêt ;
  • l’événement error qui se déclenche lorsque la requête n’a pas pu aboutir ;
  • L’événement progress qui se déclenche à intervalles réguliers et nous permet de savoir où en est notre requête.

Au sein du gestionnaire d’événement load, on va déjà vouloir tester la valeur du statut code HTTP pour savoir si notre requête a bien abouti ou pas. Pour cela, nous allons observer la valeur de la propriété status de l’objet XMLHttpRequest.

Les statuts code HTTP les plus fréquents sont les suivants :

  • 100 Continue : tout fonctionne jusqu’à présent; le client devrait continuer avec la requête ;
  • 200 OK : Les requête a été un succès ;
  • 301 Moved Permanently : L’identifiant de ressource unique (URI) relatif à la ressource demandée a changé de localisation de façon permanente ;
  • 302 Found : L’identifiant de ressource unique (URI) relatif à la ressource demandée a changé de localisation de façon temporaire ;
  • 304 Not Modified : Indique au client que la réponse n’a pas été modifiée depuis le dernier accès et qu’il peut utilisée la version en cache ;
  • 401 Unauthorized : Indique que le client doit s’identifier s’il veut accéder à la réponse ;
  • 403 Forbidden : Indique que le client n’a pas l’autorisation d’accéder à ce contenu ;
  • 404 Not Found : Le serveur n’a pas pu trouver la ressource demandée ;
  • 500 Internal Server Error : Le serveur a rencontré une situation qu’il ne peut pas gérer.

Ici, on va généralement tester si le statut code de notre réponse est bien égal à 200 en testant donc si la propriété status contient bien cette valeur. Si c’est le cas, on va pouvoir manipuler les données envoyées par le serveur.

Pour accéder à ces données, on va pouvoir utiliser la propriété response de l’objet XMLHttpRequest qui contient la réponse du serveur sous le format précisé par reponseType lors de l’envoi de la requête.

See the Pen
Cours JavaScript 17.3.1
by Pierre (@pierregiraud)
on CodePen.

Si vous travaillez en local, il est normal que la requête ci-dessus échoue (même en renseignant une bonne URL). Cela est dû à la politique CORS (Cross Origin Resource Sharing) qui interdit certaines requêtes pour protéger les utilisateurs. Nous reparlerons de cela plus tard.

Utiliser la propriété readyState et le gestionnaire onreadystatechange

Une autre méthode consiste à observer la valeur de la propriété readyState de l’objet XMLHttpRequest pour déterminer l’état d’avancement de la requête. On préfère cependant aujourd’hui utiliser les gestionnaires d’événements load, progress et error.

Pour information, les valeurs possibles de readyState sont les suivantes :

ValeurEtatDescription
0UNSENTLe client a été créé mais open() n’a pas encore été appelée
1OPENEDopen() a été appelée
2HEADERS_RECEIVEDsend() a été appelée et l’en-tête et le statut sont disponibles
3LOADINGLes données sont en train d’être téléchargées
4DONEL’opération est complète

Si on choisit d’utiliser readyState pour suivre l’avancement de notre requête, on va alors utiliser un gestionnaire d’événement onreadystatechange qui va être appelé dès que la valeur de readyState change.

On passe une fonction anonyme à ce gestionnaire pour gérer la réponse. Dans cette fonction anonyme, on teste déjà que la valeur de readyState est bien égale à 4 ou à DONE. Cela signifie qu’on a reçu la réponse du serveur dans son intégralité et qu’on va donc pouvoir l’exploiter.

Ensuite, on teste la valeur du statut code de la réponse HTTP en observant la valeur de la propriété status de l’objet XMLHttpRequest pour savoir si notre requête est un succès ou pas.

 

Effectuer des requêtes cross-origin – CORS

On parle de requête “cross-origin” lorsqu’on demande l’accès à une ressource qui provient d’un domaine, d’un protocole ou d’un port différent de ceux utilisés par la page effectuant la requête.

Pour des raisons de sécurité, ce type de requête est restreint : par défaut, on ne va pouvoir effectuer des requêtes que vers la même origine que la page qui effectue la requête. Le CORS nous permet cependant d’effectuer des requêtes cross-origin sous certaines conditions.

Le “Cross-origin resource sharing” (CORS) ou “partage des ressources entre différentes origines multiples” est un mécanisme qui consiste à ajouter des en-têtes HTTP afin de permettre à un agent utilisateur d’accéder à des ressources d’un serveur situé sur une autre origine que le site courant.

Pour pouvoir effectuer une requête cross-origin de type GET à partir d’un objet XMLHttpRequest, il va falloir réunir deux conditions :

  • On va devoir passer la valeur true à la propriété withCredentials de notre objet XMLHttpRequest ;
  • Le serveur (destinataire de notre requête) doit renvoyer un en-tête contenant Access-Control-Allow-Origin: * qui signifie que la ressource demandée est accessible depuis n’importe quel domaine.

 

Liste des propriétés et méthodes de l’objet XMLHttpRequest

Pour information, vous pourrez trouver ci-dessous un récapitulatif des propriétés et des méthodes de l’objet XMLHttpRequest ainsi qu’une rapide description.

Les propriétés de l’objet XMLHttpRequest

  • readyState = retourne un entier entre 0 et 4 qui correspond à l’état de la requête ;
  • onreadystatechange = gestionnaire d’événements appelé lorsque la valeur de readyState change ;
  • responseType = chaine de caractères précisant le type de données contenues dans la réponse ;
  • response = renvoie un objet JavaScript, ArrayBuffer, Blob, Document ou DOMString, selon la valeur de responseType, qui contient le corps de la réponse ;
  • responseText = retourne un DOMString qui contient la réponse serveur sous forme de texte ou null si la requête a échoué ;
  • responseURL = retourne une URL sérialisée de la réponse serveur ou la chaine de caractères vide si l’URL est null ;
  • responseXML = retourne un Document qui contient la réponse serveur ou null si la requête a échoué ;
  • status = retourne de statut code HTTP de la réponse ;
  • statusText = retourne un DOMString contenant la réponse complète HTTP (statut code + texte de la réponse) ;
  • timeout = représente le nombre de millisecondes accordées à un requête avant qu’elle ne soit automatiquement close ;
  • ontimeout = gestionnaire d’événements appelé lorsque la requête dépasse le temps accordé par timeout ;
  • upload = objet XMLHttpRequestUpload représentant la progression du téléchargement ;
  • withCredentials = booléen représentant si les requêtes d’accès et de contrôle cross-sites doivent être faites en utilisant des informations d’identification telles que les cookies ou les en-têtes d’autorisation.

Les méthodes de l’objet XMLHttpRequest

  • open() = initialise une requête en JavaScript ;
  • send() = envoie une requête asynchrone par défaut ;
  • abort() = abandonne la requête si celle-ci a déjà été envoyée ;
  • setRequestHeader() = définit la valeur de l’en-tête HTTP de la requête ;
  • getResponseHeader() = retourne la chaine de caractère contenant le texte de l’en-tête de la réponse spécifié ou null si la réponse n’a pas été reçue ;
  • getAllResponseHeaders() = retourne la réponse de tous les en-têtes ou null si aucune réponse n’a été reçue ;
  • overrideMimeType() = surcharge le type MIME retourné par le serveur.

Laisser un commentaire