XMLHttpRequest ( XHR ) est une API sous la forme d'un objet JavaScript dont les méthodes transmettent les requêtes HTTP d'un navigateur Web à un serveur Web . Les méthodes permettent à une application basée sur un navigateur d'envoyer des requêtes au serveur une fois le chargement de la page terminé et de recevoir des informations en retour. XMLHttpRequest est un composant de la programmation Ajax . Avant Ajax, les hyperliens et les soumissions de formulaires étaient les principaux mécanismes d'interaction avec le serveur, remplaçant souvent la page actuelle par une autre.
Histoire
Le concept de XMLHttpRequest a été conçu en 2000 par les développeurs de Microsoft Outlook . Le concept a ensuite été implémenté dans le navigateur Internet Explorer 5 (2001). Cependant, la syntaxe d'origine n'utilisait pas l' XMLHttpRequest
identifiant . À la place, les développeurs ont utilisé les identifiants ActiveXObject("Msxml2.XMLHTTP")et ActiveXObject("Microsoft.XMLHTTP"). Depuis Internet Explorer 7 (2006), tous les navigateurs prennent en charge l' XMLHttpRequestidentifiant.
L' XMLHttpRequestidentifiant est désormais la norme de facto dans tous les principaux navigateurs, y compris le moteur de mise en page Gecko de Mozilla (2002), Safari 1.2 (2004) et Opera 8.0 (2005).
Normes
Le World Wide Web Consortium (W3C) a publié une version préliminaire de spécification pour l' objet XMLHttpRequest le 5 avril 2006. Le 25 février 2008, le W3C a publié la version préliminaire de spécification de niveau 2. Le niveau 2 a ajouté des méthodes pour surveiller la progression des événements, autoriser les requêtes intersites et gérer les flux d'octets. Fin 2011, la spécification de niveau 2 a été intégrée à la spécification d'origine.
Fin 2012, le WHATWG a repris le développement et maintient un document vivant utilisant Web IDL .
Usage
En général, l’envoi d’une requête avec XMLHttpRequest comporte plusieurs étapes de programmation.
- Créez un objet XMLHttpRequest en appelant un constructeur :
var requête = nouvelle XMLHttpRequest ();
- Appelez la méthode « open » pour spécifier le type de demande, identifier la ressource concernée et sélectionner une opération synchrone ou asynchrone :
requête . open ( 'GET' , '/api/message' , true /* asynchrone */ );
- Pour une requête asynchrone, définissez un écouteur qui sera averti lorsque l'état de la requête change :
requête . onreadystatechange = écouteur ;
- Lancez la requête en appelant la méthode « send » :
demande . envoyer ();
- Répondez aux changements d'état dans l'écouteur d'événements. Si le serveur envoie des données de réponse, par défaut, elles sont capturées dans la propriété « responseText ». Lorsque l'objet arrête de traiter la réponse, il passe à l'état 4, l'état « terminé ».
function listener () { // Vérifie si la requête est effectuée et réussie. if ( request . readyState == 4 && request . status == 200 ) console . log ( request . responseText ); // Affiche le texte. }
Outre ces étapes générales, XMLHttpRequest propose de nombreuses options permettant de contrôler la manière dont la requête est envoyée et la manière dont la réponse est traitée. Des champs d'en-tête personnalisés peuvent être ajoutés à la requête pour indiquer comment le serveur doit l'exécuter, et les données peuvent être téléchargées sur le serveur en les fournissant dans l'appel « send ». La réponse peut être analysée à partir du format JSON dans un objet JavaScript facilement utilisable, ou traitée progressivement à mesure qu'elle arrive plutôt que d'attendre le texte entier. La requête peut être abandonnée prématurément ou configurée pour échouer si elle n'est pas terminée dans un délai spécifié.
Requêtes inter-domaines
Au début du développement du World Wide Web , il a été découvert qu'il était possible de violer la sécurité des utilisateurs en utilisant JavaScript pour échanger des informations d'un site Web avec celles d'un autre site moins réputé. Tous les navigateurs modernes mettent donc en œuvre une politique d'origine commune qui empêche de nombreuses attaques de ce type, telles que les scripts intersites . Les données XMLHttpRequest sont soumises à cette politique de sécurité, mais il arrive que les développeurs Web souhaitent intentionnellement contourner ses restrictions. Cela est parfois dû à l'utilisation légitime de sous-domaines, car, par exemple, l'exécution d'une requête XMLHttpRequest à partir d'une page créée par foo.example.compour obtenir des informations bar.example.coméchouera normalement.
Il existe plusieurs alternatives pour contourner cette fonction de sécurité, notamment l'utilisation de JSONP , le partage de ressources cross-origine (CORS) ou des alternatives avec des plugins tels que Flash ou Silverlight (tous deux désormais obsolètes). Le XMLHttpRequest cross-origine est spécifié dans la spécification XMLHttpRequest niveau 2 du W3C. Internet Explorer n'a pas implémenté CORS avant la version 10. Les deux versions précédentes (8 et 9) offraient des fonctionnalités similaires via l'API XDomainRequest (XDR). CORS est désormais pris en charge par tous les navigateurs modernes (bureau et mobile).
Le protocole CORS présente plusieurs restrictions, avec deux modèles de prise en charge. Le modèle simple ne permet pas de définir des en-têtes de requête personnalisés et omet les cookies . De plus, seules les méthodes de requête HEAD, GET et POST sont prises en charge, et POST n'autorise que les types MIME suivants : « text/plain », « application/x-www-urlencoded » et « multipart/form-data ». Seul « text/plain » était initialement pris en charge. L'autre modèle détecte lorsqu'une des fonctionnalités non simples est demandée et envoie une demande préalable au serveur pour négocier la fonctionnalité.
Récupérer une alternative
Le flux de programme utilisant des rappels XHR asynchrones peut présenter des difficultés de lisibilité et de maintenance. ECMAScript 2015 (ES6) a ajouté la construction promisefetch() pour simplifier la logique asynchrone. Les navigateurs ont depuis implémenté l' interface alternative pour obtenir la même fonctionnalité que XHR en utilisant des promesses au lieu de rappels.
Fetch est également standardisé par WHATWG.
Exemple
fetch ( '/api/message' ) . then ( response => { if ( response . status != 200 ) throw new Error ( 'La requête a échoué' ); return response . text (); }) . then ( text => { console . log ( text ); });