L'AJAX est un outil clé du développement d'applications Web moderne. Il vous permet d'envoyer et de recevoir des données de manière asynchrone au serveur, puis de l'analyser en JavaScript. Ajax est l'abréviation de JavaScript asynchrone et XML (JavaScript asynchrone et XML).
Le nom de la spécification CORE AJAX est hérité de l'objet JavaScript utilisé pour créer et initier des demandes: xmlhttprequest. Il y a deux niveaux de cette spécification. Tous les navigateurs grand public implémentent le premier niveau, qui représente le niveau de fonctionnalité de base. Le deuxième niveau étend la spécification initiale, intègre des événements supplémentaires et certaines fonctionnalités pour faciliter la collaboration avec les éléments de formulaire et prend en charge certaines spécifications connexes.
1. Ajax commence
La clé d'Ajax se trouve dans l'objet XMLHTTPRequest, et la façon de comprendre cet objet est de regarder un exemple. Le code suivant montre l'utilisation simple de l'objet XMLHttpRequest:
<! Doctype html> <html lang = "en"> <éadf> <meta charset = "utf-8"> <ititle> Exemple </ title> </ad> </ body> <div> </ bouton> </ Button> <Futonteur> Cherries </ftones> <Fit Button> Bananas </utton> </v> <div Id = "Target"> Appuyez sur un bouton </ div> var boutons = document.getElementsByTagName ("Button"); pour (var i = 0; i <Buttons.length; i ++) {Buttons [i] .OnClick = BrochebuttonPress; } // Le script appellera cette fonction pour répondre à la fonction de clic du bouton Cliquez sur le manchebuttonpress (e) {// Créer un nouvel objet XMLHTTPRequest var httprequest = new XMLHttPrequest (); // Définissez un gestionnaire d'événements pour l'événement OnReadyStateChange httpRequest.OnreadyStateChange = HandlerResponse; // Utilisez la méthode ouverte pour spécifier la méthode HTTP et l'URL pour demander (c'est-à-dire, dites à l'objet httpRequest ce que vous voulez faire) httprequest.open ("get", e.target.innerhtml + ". Html"); // Aucune donnée n'est envoyée au serveur ici, donc la méthode d'envoi n'a pas de paramètres disponibles httpRequest.Send (); } // Traitement de la réponse // Une fois que le script appelle la méthode d'envoi, le navigateur enverra une demande au serveur en arrière-plan. Étant donné que la demande est traitée en arrière-plan, Ajax s'appuie sur des événements pour éclairer la progression de la demande. Fonction HandlerResponse (e) {// Lorsque l'événement OnReadyStateChange est déclenché, le navigateur passera un objet d'événement à la fonction de gestionnaire spécifié, et la propriété cible sera définie sur le XMLHTTPREQUEST associé à cet événement (e.target.readystate == xmlhttprequest.done && e.target.stateS == 200) document.getElementById ("Target"). InnerHtml = e.target.ResponSeText; // Affiche le contenu du document demandé}} </cript> </ body> </html>Trois documents supplémentaires sont très simples:
<! Doctype html> <html lang = "en"> <éadf> <meta charset = "utf-8"> <tight> pommes </title> <style> img {float: left; padding: 2px; margin: 5px; border: medium double noir; background-Color: LightGrey; Largeur: 100px; hauteur: 100px;} </ style> </ head> <body> <p> <img src = "../ img / show-page / img_apples.jpg" /> page pour les pommes. </p> </ body> </html>L'effet est illustré dans la figure ci-dessous:
Lorsque l'utilisateur clique sur chaque bouton Fruit, le navigateur s'exécute de manière asynchrone et récupère le document demandé, tandis que le document principal n'est pas rechargé. Il s'agit d'un comportement typique de l'Ajax.
2. Utilisation d'événements Ajax
Après avoir créé et exploré un exemple simple, vous pouvez commencer à creuser dans les fonctionnalités prises en charge par l'objet XMLHTTPRequest et comment les utiliser dans votre demande. Le point de départ est les événements supplémentaires définis dans la spécification du deuxième niveau:
La plupart de ces événements sont déclenchés à un moment précis pendant la demande. Les deux événements sont des exceptions, ReadyStateChange et Progress, qui peuvent être déclenchées plusieurs fois pour fournir des mises à jour de progrès.
Lorsque ces événements sont planifiés, le navigateur utilise un objet d'événement régulier pour l'événement ReadyStateChange et un objet ProgressEvent pour d'autres événements. L'objet ProgressEvent définit tous les membres de l'objet de l'événement et ajoute ces membres décrits dans la figure suivante:
Le code suivant montre comment utiliser ces événements:
<! Doctype html> <html lang = "en"> <éadf> <meta charset = "utf-8"> <tapie> Exemple </Title> <style> TABLE {margin: 10px; border-Collapse: Emballapse; float: gauche;} div {margin: 10px;} td, th {padding: 4px;} </ style> </ head> <body> <div> <futton> pommes </utton> </ bouton> cerises </ bouton> <frut-boutons> bananes </ftones> </v> <table id = "events"> </pall type = "application / javascript"> var boutons = document.getElementsByTagName ("bouton"); pour (var i = 0; i <Buttons.length; i ++) {Buttons [i] .OnClick = BrochebuttonPress; } var httpRequest; Fonction HorplebuttonPress (e) {ClearEventDetails (); httpRequest = new xmlHttpRequest (); httpRequest.OnreadyStateChange = HandleResponse; httpRequest.OnError = handleerror; httprequest.onload = handleload ;; httpRequest.onLoadEnd = handleloadend; httpRequest.onLoadStart = handleloadstart ;; httpRequest.onProgress = handleProgress; httprequest.open ("get", e.target.innerhtml + ". html"); httpRequest.send (); } Fonction HandleResponse (e) {displayEventDetails ("ReadyState (" + httprequest.readystate + ")") if (e.target.readystate == xmlhttprequest.done && e.target.status == 200) {Document.getElementyId; }} fonction mancheerror (e) {displayEventDetails ("error", e);} fonction handleload (e) {displayEventDetails ("Load", e);} fonction HandleLoadend (e) {displayEventDetails ("loadEnd", e);} fonction handleloadend (e) {displayEventDetIls (". fonction handleloadstart (e) {displayEventDetails ("LoadStart", e);} fonction mange "<tr> <th> Event </ th> <th> Longueurcompitable </th> <th> chargé </th> <th> total </th>"; } fonction displayEventDetails (EventName, e) {if (e) {document.getElementById ("Events"). InnerHtml + = "<Tr> <Td>" + EventName + "</td> <td>" + e.Lengthcompitable + " e.total + "</td> </tr>"; } else {document.getElementById ("Events"). InnerHtml + = "<tr> <Td>" + Eventname + "</td> <td> na </td> <td> na </td> <td> na </td> <td> na </td> </tr>"; }} </ script> </ body> </html>Il s'agit d'une variation de l'exemple précédent, en enregistrant un gestionnaire pour certains événements et en créant un enregistrement pour chaque événement traité dans un élément de table. À partir de l'image suivante, vous pouvez voir comment le navigateur Firefox déclenche ces événements.
3. Gérer les erreurs
Deux types d'erreurs doivent être prêts à l'attention lors de l'utilisation de l'Ajax. La différence entre eux provient de différentes perspectives.
Le premier type d'erreur est un problème vu du point de vue de l'objet XMLHTTPRequest: certains facteurs empêchent la demande d'être envoyée au serveur. Par exemple, DNS ne peut pas résoudre le nom d'hôte, la demande de connexion est refusée ou l'URL n'est pas valide.
Le deuxième type de problème est le problème vu du point de vue de l'application, pas l'objet XMLHTTPRequest. Ils se produisent lorsque la demande est envoyée avec succès au serveur, qui reçoit la demande, traite et génère une réponse, mais la réponse ne pointe pas à ce que vous attendez. Par exemple, si l'URL demandée n'existe pas, ce type de problème se produit.
Il existe trois façons de gérer ces erreurs, comme indiqué dans le code suivant:
3.1 Erreurs de réglage de la gestion
Le premier type de problème qui doit être traité est de transmettre des données incorrectes à l'objet XMLHTTPresquest, comme une URL incorrecte. Ils sont extrêmement enclins à se produire lors de la génération d'URL en fonction de l'entrée utilisateur. Pour simuler ce type de problème, le document ci-dessus a un bouton qui ajoute une URL de mauvaise étiquette (mauvaise URL). Appuyez sur ce bouton appeler la méthode ouverte dans le formulaire suivant:
httprequest.open ("get", "http: //")
Il s'agit d'une erreur qui empêche l'exécution de la demande, et une erreur est lancée lorsqu'un événement comme celui-ci se produit dans l'objet XMLHTTPRequest. Cela signifie qu'une instruction Try ... Catch est nécessaire pour entourer le code qui définit la demande, comme ceci:
essayez {... httprequest.open ("get", "http: //") ... httprequest.send (); } catch (error) {displayerrormsg ("try / catch", error.sessage)}La clause Catch vous donne une chance de vous remettre de l'erreur. Vous pouvez choisir d'inviter l'utilisateur pour une valeur, ou de retomber à l'URL par défaut, ou simplement de rejeter la demande. Dans cet exemple, la fonction Displayerrormsg est appelée pour afficher le message d'erreur.
3.2 Erreurs de demande de traitement
Le deuxième type d'erreur se produit lorsque la demande a été générée mais il y a d'autres erreurs. Pour simuler ce type de problème, un bouton étiqueté Bad Host (Error Host) a été ajouté dans l'exemple. Lorsque ce bouton est enfoncé, la méthode ouverte sera appelée pour accéder à une URL indisponible:
httprequest.open ("get", http: //www.ycboitt.com/nopage.html)Il y a deux problèmes avec cette URL. Le premier problème est que le nom d'hôte ne peut pas être résolu par DNS, donc le navigateur ne peut pas générer de connexion de serveur. Ce problème sait que l'objet XMLHttpRequest ne devient évident que lorsqu'il commence à générer la demande, donc il signale les erreurs de deux manières. Si vous enregistrez un auditeur pour un événement d'erreur, le navigateur enverra un objet d'événement à votre écouteur. Voici les fonctions utilisées dans l'exemple:
Fonction HandleError (e) {displayerrormsg ("Erreur Event", httprequest.status + httprequest.statustext); }Lorsque de telles erreurs se produisent, le degré d'information qui peut être obtenu à partir de l'objet XMLHTTPRequest dépend du navigateur. Malheureusement, dans la plupart des cas, le statut avec une valeur de 0 et une valeur de statistique vierge seront obtenus.
Le deuxième problème est que l'URL et la demande générée ont des sources différentes, qui ne sont pas autorisées par défaut. Vous pouvez généralement envoyer uniquement des demandes AJAX à l'URL d'origine même qui charge le script. Lorsqu'un navigateur rapporte ce problème, une erreur peut être lancée ou un événement d'erreur peut être déclenché. Différents navigateurs le gèrent différemment. Différents navigateurs vérifient également la source à différents moments dans le temps, ce qui signifie que le navigateur peut ne pas toujours être vu mettant en évidence le même problème. Le partage des ressources croisées peut être utilisé pour contourner les restrictions homologues.
3.3 Gestion des erreurs d'application
Le dernier type d'erreur se produit lorsque la demande se termine avec succès (du point de vue de l'objet XMLHTTPRequest), mais ne renvoie pas les données souhaitées. Pour créer de tels problèmes, ajoutez un bouton avec le concombre d'étiquette dans l'exemple ci-dessus. Appuyez sur ce bouton générera une URL de demande similaire aux boutons de pommes, de cerises et de bananes, mais le document CuCumber.html n'existe pas sur le serveur.
Il n'y a aucune erreur dans ce processus lui-même (car la demande a été terminée) et il est nécessaire de déterminer ce qui se passe en fonction de l'attribut d'état. Lors de la demande d'un document existant, le code d'état 404 sera obtenu, ce qui signifie que le serveur ne peut pas trouver le document demandé. Vous pouvez voir comment l'exemple gère les codes d'état autres que 200 (ce qui signifie OK):
if (httprequest.status == 200) {Target.InnerHtml = httpRequest.ResponSext; } else {document.getElementById ("Statusmsg"). innerHtml = "Status:" + httprequest.status + "" + httprequest.statustext; }Dans cet exemple, les valeurs de l'état et des statistiques sont simplement affichées. Dans les applications réelles, la récupération doit être effectuée de manière utile et significative (comme afficher un contenu alternatif ou un avertissement des utilisateurs qu'il y a un problème, selon celui qui convient le plus à l'application).
4. Obtenez et définissez des en-têtes
À l'aide de l'objet XMLHTTPRequest, vous pouvez définir l'en-tête de demande envoyé sur le serveur et l'en-tête dans la réponse du serveur.
4.1 Écraser la méthode HTTP pour les demandes
Il n'est généralement pas nécessaire d'ajouter ou de modifier l'en-tête dans la demande AJAX. Le navigateur sait quoi envoyer et le serveur sait comment répondre. Cependant, il existe plusieurs exceptions. Le premier est l'en-tête X-HTTP-Method-Override.
La norme HTTP est souvent utilisée pour demander et transmettre des documents HTML sur Internet, et il définit de nombreuses méthodes. La plupart des gens connaissent Get and Post parce qu'ils sont les plus utilisés. Cependant, il existe d'autres méthodes (y compris la put et la suppression) qui sont utilisées pour donner un sens à l'URL demandée au serveur, et cette utilisation est en augmentation. Par exemple, si vous souhaitez afficher un enregistrement d'utilisateur, vous pouvez générer une telle demande:
httprequest.open ("get", "http: // myserver / disques / freeman / adam");Seule la méthode HTTP et l'URL demandée sont affichées ici. Pour que cette demande fonctionne bien, le côté serveur doit être en mesure de comprendre la demande par l'application et de les convertir en un élément de données approprié à renvoyer au serveur. Si vous souhaitez supprimer les données, vous pouvez l'écrire comme ceci:
httpRequest.open (" Delete ", "http: // myserver / disques / freeman / adam");La clé ici est d'exprimer ce que vous voulez que le serveur fasse via HTTP, plutôt que de le coder dans l'URL d'une manière ou d'une autre.
Le problème avec l'utilisation des méthodes HTTP de cette manière est que de nombreuses technologies Web grand public ne prennent en charge que Get and Publiage, et de nombreux pare-feu autorisent uniquement les demandes et les demandes de publication. Il existe une approche idiomatique pour éviter cette limitation, qui consiste à utiliser l'en-tête X-HTTP-Method-Override pour spécifier la méthode HTTP que vous souhaitez utiliser, mais le formulaire est commercialisé et envoie une demande postale. La démonstration du code est la suivante:
<! Doctype html> <html lang = "en"> <éad> <meta charset = "utf-8"> <ititle> Exemple </ title> </ head> </ body> <div> <fonton> pommes </ bouton> <utton> cerises </fton> <fruit> Bananas </frut> </v> <div id = "Target"> document.getElementsByTagName ("Button"); pour (var i = 0; i <Buttons.length; i ++) {Buttons [i] .OnClick = BrochebuttonPress; } var httpRequest; Fonction GrowbuttonPress (e) {httpRequest = new xmlHttpRequest (); httpRequest.OnreadyStateChange = HandleResponse; httprequest.open ("get", e.target.innerhtml + ". html"); httprequest.setRequestHeader ("x-http-méthode-override", "supprimer"); httpRequest.send (); } Fonction HandleError (E) {Displayerrormsg ("Événement d'erreur", httprequest.status + httprequest.statustext); } fonction HandleResSon () {if (httprequest.readystate == 4 && httprequest.status == 200) {document.getElementById ("Target"). InnerHtml = httprequest.ResponSeText; }} </ script> </ body> </html>Dans cet exemple, la méthode setRequestHeader sur l'objet XMLHTTPRequest est utilisée pour indiquer que la demande est vouée être traitée sous la forme d'une méthode de suppression HTTP. Veuillez noter que je définis cet en-tête uniquement après avoir appelé la méthode ouverte. Si vous essayez d'utiliser la méthode setRequestHeader avant la méthode ouverte, l'objet XMLHTTPRequest jette une erreur.
PS: L'écrasement de HTTP nécessite le cadre d'application Web côté serveur pour comprendre la convention de X-HTTP-Method-Override, et votre application côté serveur doit être définie pour trouver et comprendre ces méthodes HTTP moins.
4.2 Désactiver la mise en cache de contenu
Le deuxième en-tête utile qui peut être ajouté aux demandes AJAX est le contrôle du cache, ce qui est particulièrement utile lors de l'écriture et de la débogage des scripts. Certains navigateurs cachent le contenu obtenu via les demandes AJAX et ne le demanderont pas à nouveau pendant la session de navigation. Pour l'exemple précédent, cela signifie que les modifications sur pommes.html, ceriries.html et bananas.html ne seront pas immédiatement reflétées dans le navigateur. Le code suivant montre comment définir les en-têtes pour éviter ceci:
httpRequest = new xmlHttpRequest (); httpRequest.OnreadyStateChange = HandleResponse; httprequest.open ("get", e.target.innerhtml + ". html"); httprequest.setRequestHeader ("Cache-Control", "No-cache"); httpRequest.send ();La façon de définir l'en-tête est la même que dans l'exemple précédent, mais cette fois, l'en-tête est le contrôle du cache, et la valeur souhaitée est sans cache. Après avoir placé cette instruction, si le contenu demandé par Ajax modifie, il sera reflété la prochaine fois que le document sera demandé.
4.3 Lisez l'en-tête de réponse
L'en-tête HTTP envoyé par le serveur lors de la réponse à une demande AJAX peut être lu via les méthodes GetResponseHeader et GetAllResponseHeaders. Dans la plupart des cas, vous n'avez pas besoin de vous soucier de ce qui est dans l'en-tête, car ils font partie des transactions interactives entre le navigateur et le serveur. Le code suivant montre comment utiliser cette propriété:
<! Doctype html> <html lang = "en"> <éad> <meta charset = "utf-8"> <meta tenty = "width = device-width, user-scalable = no" name = "Viewport" /> <meta name = "auteur" contenu = "ye chaoluka" /> <méta = "Description" Contenu = "un exemple simple" href = "../ img / ycdoit.ico" type = "image / x-icon" rel = "icône de raccourci" /> <style> # alhendhers, # cheader {border: moyen solide noir; padding: 2px; margin: 2px;} </ style> </ head> <body> <v> <bouton> complete </ bouton> </ bouton> <Fut-Button> Bananas </ Button> </div> <div id = "cheader"> </ div> <div id = "allheaders"> </div> <div id = "Target"> Appuyez sur un bouton </v> <prissle> var boutons = document.getElementsByTagName ("Button"); pour (var i = 0; i <Buttons.length; i ++) {Buttons [i] .OnClick = BrochebuttonPress; } var httpRequest; Fonction GrowbuttonPress (e) {httpRequest = new xmlHttpRequest (); httpRequest.OnreadyStateChange = HandleResponse; httprequest.open ("get", e.target.innerhtml + ". html"); httprequest.setRequestHeader ("Cache-Control", "No-cache"); httpRequest.send (); } Fonction HandleResponse () {if (httpRequest.readyState == 2) {document.getElementById ("AllHeaders"). InnerHtml = httprequest.getAllResponseHeaders (); document.getElementById ("Cheader"). InnerHtml = httpRequest.getResponseHeader ("Content-Type"); } else if (httprequest.readystate == 4 && httprequest.status == 200) {document.getElementById ("Target"). innerHtml = httpRequest.ResponSext; }} </ script> </ body> </html>Les rendus sont les suivants:
Selon cette figure, nous pouvons voir que le logiciel du serveur Web que le serveur de développement exécute est IntelliJ Idea 15.0.4, et la dernière fois que le document Pommes.html a été modifié était le 27 juin (mais la capture d'écran était le 5 juillet).