Concepteur de Projet Digital – Mastère spécialisé

La double-compétence, par l'INA et Telecom ParisTech

Corrigé TP AJAX

TP Javascript AJAX et XML

Ce TP est à l’adresse

http://perso.telecom-paristech.fr/~moissina/CPD/TPAjax/TPAjaxXML.htm

Dans ce qui suit, les commentaires et éléments de solutions sont en bleu à la suite de chaque partie du sujet. Peu à peu de plus en plus de procédés d’expression d’actions en javascript ont été introduites en avançant dans le TP.

Dans ce TP, nous allons poursuivre l’exploration des possibilités de programmation intégrées à des pages Web.

Pour simplifier ce TP, nous allons utiliser une librairie très utilisée sur le Web nommée jQuery.

Un avantage de jQuery est notamment de masquer des différences qu’il peut y avoir d’un navigateur à l’autre dans l’implémentation d’AJAX.

Les éléments nécessaires pour ce TP vous seront donnés au fur et à mesure des besoins.

Intégration de jQuery et d’un code source personnel dans votre page Web

Intégrez ces lignes à votre page HTML que vous avez déjà ou que vous créerez pour ce TP.

 

 

Bien sûr, indiquez le bon chemin d’accès au fichier jQuery dans l’attribut src de la première balise script (nous verrons plus loin qu’il est possible de référencer une version de jQuery sur le réseau).

Pour l’instant, créez un fichier script.js vide.

De la façon habituelle, intégrez un morceau de script dans votre page qui s’exécutera seulement lorsque votre page est chargée.

Affichez votre page pour vérifier que tout va bien en passant par un serveur ( ?)AMP (XAMP, MAMP, WAMP) ou sur votre public_html de votre compte personnel de l’école.

Nous recommandons de faire les tests dans le navigateur Chrome, car à la date d’écriture de ce document, les outils de développements intégrés à Chrome semblent fournir un peu plus de facilités dans les diagnostics des problèmes.

Si vous visez des navigateurs un peu anciens vous devez indiquer le type du script; cela n’est plus nécessaire avec HTML5. Cela donnerait

Vous créez donc un document HTML minimal. Dans une variante de l’extrait HTML ci-dessus, on pourrait référencer jQuery sur le réseau. Le résultat peut ressembler à ça:

Comme cela a été vu par ailleurs, avant d’exécuter nos propres code, on doit s’assurer que la page web est complètement chargée. Avec jQuery, cela se fait avec le code suivant

L’appel à alert peut être enlevé, il ne sert qu’à pouvoir vérifier que les base que nous avons mises en place ici fonctionnent.

Chargement dans la page d’un fichier XML

A l’adresse suivante

http://perso.telecom-paristech.fr/~moissina/CPD/TPAjax/data/mairie-09001-01.xml

Ici, j’ouvre le lien et je sauve son contenu dans le fichier donnees.xml dans mon dossier de travail.

se trouve un premier fichier XML qui va servir à notre travail. Vous allez le charger dans votre dossier de travail.

Dans le fichier script.js, définissez une fonction qui va appeler le fichier XML en utilisant la fonction jquery ajax dont vous chercherez la documentation.

Appelez cette fonction au chargement de votre page.

Note : on parle souvent de XHR au sujet des appels AJAX. XHR désigne de façon abrégée la fonction de base qui sert aux appels AJAX : XMLHttpRequest (vous devez avoir idée de quoi on parle quand on parle d’Ajax, de XHR, de XMLHttpRequest)

Vous devez utiliser la méthode done du résultat de l’appel ajax. La méthode done prend en paramètre une fonction ; vous pouvez lui passer la fonction suivante

Ici, il faut chercher de la documentation de la méthode ajax définie par jQuery.

Une recherche Google de « jquery ajax done » propose parmi les premiers liens

http://api.jquery.com/jquery.ajax/ dans cette page, je cherche où apparaît ‘done’ et plus précisément, pour gagner du temps sans tout lire, je cherche un exemple de code (en prévoyant de lire plus de documentation et de tutoriels ensuite, pour comprendre en détail); je trouve un bout assez simple:

J’ajoute ça dans mon fichier script.js, ce qui donne:

Si je teste tout de suite ma page, cela ne fonctionne pas. Je peux ouvrir les outils de développements. Je vois dans la fenêtre ‘console’ le message d’erreur suivant

GET http://127.0.0.1/www/cpd/20152016/TPAjax/example.php 404 (Not Found)

qui m’indique que le chargement de la page a échoué parce que le fichier example.php était demandé, mais pas trouvé. J’avais fait un copier/coller un peu rapide: je dois référencer un fichier de données qui existe: données.xml. Ce qui donne:

Explication:

la fonction ajax envoie une requête à un serveur. Ici elle demande le fichier donnees.xml au même serveur que celui d’où vient la page et qui doit se trouver à côté du fichier html de la page, puisqu’il n’y a pas de chemin relatif du genre js/donnees.xml. Comme la réponse à une requête à un serveur web peut mettre un peu de temps à arriver, au lieu de bloquer tout sur la page, la méthode ajax fait l’appel et mémorise des fonctions qui pourront être appelées dès que la réponse à la requête va arriver. En fait, ici, on configure 3 fonctions: une sera appelée lorsque la réponse arrive avec succès, que l’on configure avec la méthode done; une sera appelée si la requête échoue, que l’on configure avec la méthode fail; enfin, une sera appelée quoi qu’il arrive, que l’on configure avec la méthode always.

Autre lien trouvé dans la recherche précédente:

http://api.jquery.com/load/ ce lien propose une alternative à la méthode ajax, mais la recherche effectuée suggère bien une relation avec la méthode ajax

function mafonction(data)

{

alert(data) ;

}

En supposant que data désigne les données reçues par l’appel AJAX.

Chargez la page dans le navigateur.

Que constatez-vous ? Qu’en déduisez-vous ?

L’alert affiche une boite de dialogue avec l’indication [object XMLDocument], ce qui suggère que data est un objet javascript de type XMLDocument. Nous pourrions aller chercher de la documentation sur XMLDocument (par exemple, avec une recherche Google ‘js XMLDocument’, on trouve https://developer.mozilla.org/en-US/docs/Web/Guide/Parsing_and_serializing_XML -généralement les documentations de mozilla sont plutot bien faites-, ou http://www.w3schools.com/xml/dom_intro.asp -W3Schools est une source de qualité). Nous allons plutot, comme indiqué ensuite, utiliser jQuery.

Utiliser les données reçues : construire des éléments HTML

Vous avez pu constater que AJAX vous pemet de récupérer un objet de type XMLDocument ([object XMLDocument])

Maintenant, vous allez utiliser les données de ce document XML pour « peupler » votre page HTML.

La plupart des modes d’accès à des parties d’un document HTML proposées par jQuery fonctionnent avec un document XML.

Par exemple, si data désigne votre XML Document

$(data)

Permet à jQuery de ‘naviguer’ sur le XML et

$(data).find(« Latitude »).text() ;

Vous donne la valeur de la balise Latitude du document.

Construisez votre page Web sur ce principe

Méthodes utiles :

text

find

attr

Nous sommes prêts à utiliser  des données provenant du document XML. Avant de les utiliser dans la page, on va faire une récupération simple, pour vérifier qu’on y arrive.

Quand on teste notre page, l’alert affiche une valeur numérique, celle de la latitude issue du fichier XML.

Explication:

$ désigne jQuery

$(data) sélectionne data comme données courantes pour jQuery et permet ensuite d’utiliser les facilités de jQuery pour accéder à des parties d’un document construit avec des balises (d’habitude, c’est du HTML, mais ça marche aussi sur du XML)

Cette ligne trouve une balise Latitude, où quelle soit dans le document XML.

Regardez notamment comment chainer les find.

S’il y avait plusieurs balises de même nom, on récupérerait un ensemble d’éléments. Il faudrait alors éventuellement chainer les find pour trouver le bon.  Par exemple, si dans notre fichier XML, la balise EditeurSource avait une sous-balise Nom:

  • pour récupérer le nom de l’éditeur, on pourrait utiliser

  •  
  • pour récupérer le nom de l’organisme, on pourrait utiliser

Dans le premier exemple, le premier find trouve la balise EditeurSource et chainant un deuxième, on trouve la balise Nom contenue dans la balise EditeurSource.

Utiliser les données reçues : ajouter une carte

En utilisant les éléments Latitude et Longitude du fichier XML, nous allons introduire une carte dans la page, centrée sur la position de la mairie.

Les possibilités utilisées sont fournies par l’API Google Maps.

Voir

https://mscpd.wp.imt.fr/files/2014/10/Javascript5Mashup.pdf

La ligne suivante doit figurer au début de votre fichier html, avec les déclarations de script :

<script type= »text/javascript » src= »http://maps.google.com/maps/api/js?sensor=false »></script>

Et une dimension doit être allouée à un div pour y afficher la carte, par exemple

<div id= »map » style= »margin-left:15px; width: 500px; height: 300px; »></div>

Ce qui donne la page HTML suivante

Nous remarquons qu’ici, les librairies javascript utilisées sont obtenues via le réseau, de préférence sans indication de protocole (http ou https). Cela permet de décharger notre serveur de la fourniture des sources de ces librairies; en plus, les librairies les plus courantes étant distribuées par des CDN -Content Delivery Network- elles sont fournies rapidement, au plus près de l’utilisateur.

Dans le document sur les mashups, on trouve un exemple de fonction javascript pour afficher une carte:

La ligne

crée un object défini dans l‘API google maps et qui sert à stocker une paire de coordonnées géographiques.

Les lignes

créent un objet javascript qui va stocker les options de la carte que nous allons créer (le niveau de zoom, le centre de la carte, le type de carte).

Les lignes

créent la carte. Il s’agit d’une fonction de l’API Google Maps, qui fait appel aux services de Google pour créer la carte et associent cette carte avec un div dans notre page (ici la référence au div où on veut mettre la carte est récupérée par son id ‘map’.

Les lignes

créent un marqueur à afficher sur la carte. C’est un marqueur fournit par l’API Google Maps. Les paramètres dont donnés dans un objet javascript, avec une propriété position qui prend la valeur de l’objet myLatlng définit précédemment, une carte sur laquelle afficher le marqueur, ici l’objet map que nous venons de créer, et enfin une propriété title, qui est une chaîne de caractère. Nous allons modifier un peu cette fonction pour prendre des valeurs de latitude et longitude tirées du document XML et utiliser le nom tiré de ce document pour la propriété title du marker. L’objet peut être défini avec des options complémentaires qu’on trouve dans la documentation de l’API Google Maps.

La dernière ligne provoque l’affichage de la carte. C’est du pur jQuery.

$(« #map ») récupère le div dont l’id est map. fadein est une fonction jQuery qui affiche un élément d’une page HTML (voir doc)

En partant de notre code de l’étape précédente, nous allons exploiter une fonction d’affichage de carte légèrement modifiée. D’abord, le code qui tire des données du document XML en vue d’afficher la carte:

Ici, la seule chose nouvelle par rapport aux étapes précédentes et l’ajout d’un appel à une fonction ‘localiser’ que nous allons devoir définir en modifiant légèrement celle présentée juste au-dessus. Cette nouvelle fonction peut être définie à la suite du code précédent.

Très peu de choses ont changées. Les coordonnées utilisées pour créer l’objet google.maps.LatLng sont reçues en paramètre de la fonction. Le troisième paramètre (nom) est utilisé comme valeur pour la propriété title du marqueur.

On a maintenant une fonction qui nous permet d’afficher différentes carte en fonction des paramètres qu’on lui passe.

 

Dans un deuxième temps, vous allez exploiter plusieurs fichiers ‘mairie’

—> Cette partie, plus délicate est traitée à part dans le document https://mscpd.wp.imt.fr/?p=118

Vous y êtes : vous avez exploité AJAX, des données XML.

En plus, elles provenaient de l’Open Data (liste des mairies à partir du site data.gouv.fr

Cross Origin

Nous allons chercher à charger les fichiers de mairie directement depuis l’adresse sur le site de telecom-paristech et analyser ce qui se passe.

Au lieu de charger les fichiers de description de mairie que vous avez chargés dans vos dossiers de serveur web, vous allez essayer les charger depuis la source indiquée précédemment.

Par exemple, si vous avez chargé le fichier mairie-09001-01.xml dans le dossier data, au lieu de charger ce fichier, chargez http://perso.telecom-paristech.fr/~moissina/CPD/TPAjax/data/mairie-09001-01.xml

Depuis un autre serveur.

Si on reprend le code simple, quelques étapes plus haut, qui exploitait les données, ce la donne

Que constatez-vous ? (vous allez surement devoir regarder dans les outils de développements du navigateur).

Ne cherchez pas à résoudre le problème, ce point sera commenté par ailleurs.

(https://onsem.wp.imt.fr/fr/ est une ressource à ce sujet)

L’alerte ‘error’ s’affiche. Dans les outils de développement, nous pouvons voir le message d’erreur

XMLHttpRequest cannot load http://perso.telecom-paristech.fr/~moissina/CPD/TPAjax/data/mairie-09001-01.xml. No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://127.0.0.1’ is therefore not allowed access.

Ce message est typique d’un problème d’accès à une origine différente de l’origine de votre page et qui n’accepte pas ce type d’accès. Un message de même nature apparait lorsque vous testez votre page en l’ouvrant directement de votre File System au lieu de l’ouvrir via un serveur.

Lire une source périodiquement

Vous allez créer un fichier message.txt qui contient un petit texte.

Dans la page HTML qui s’affiche dans le navigateur de votre utilisateur vous allez mettre un bout de script qui lit périodiquement le fichier message.txt.

Bien sur, cela veut dire que vous créez un fichier message.txt dans votre dossier de travail, contenant par exemple juste la chaine de caractères ‘test de message’.

La lecture du fichier sera effectuée avec un appel AJAX.

A la base, la lecture du fichier peut être assurée par le code suivant

On voit que l’insertion de morceau de page html se fait sur le même modèle que précédemment. Par contre, comme le fichier message est un petit fichier textuel, on utilise directement la donnée récupérer, sans besoin de code spécifique pour retrouver des portions du fichier comme en XML.

Le déclenchement périodique de cette lecture sera réalisé avec la fonction setTimeout

Comme on veut répéter l’exécution du code d’appel ajax périodiquement on va en faire une fonction qu’on va ajouter à la fin de notre fichier. ce qui va donner

La fonction message litMessage contient le même code que les appels ajax précédents. La seule différence est la ligne

 

Cette ligne indique au navigateur que lorsque 2000 millisecondes seront passées, il faudra appeler la fonction message. Ainsi, on va refaire l’appel ajax toutes les secondes.

Note : avec des navigateurs récents, on privilégierait des WebSockets pour ce genre de communication entre le client et le serveur, mais cela nous amènerait à trop de complexité côté serveur ; dans le cas des WebSockets, c’est le serveur qui décide d’envoyer un message que le client traite dès qu’il le reçoit

Dans la fonction qui reçoit le résultat de l’appel AJAX, affichez le message quelque part dans votre page, en l’ajoutant à un élément texte de la page (span ou autre).

Modifiez le fichier message.txt sur le serveur et regardez ce qui se passe.

On voit que sur le client, dans la page Web, le message est mis à jour (éventuellement avec un petit retard).

Envoyer un message au serveur

Dans votre page, vous allez ajouter une zone de texte où l’utilisateur peut entrer un texte sur le modèle suivant, par exemple :

<form onsubmit= »ecrit(); return false; »><input id= »laPhrase » type= »text » /> <input type= »submit » value= »Envoyer »/></form>

Votre fichier HTML peut ressembler à ça

Si vous avez à travailler sur les formulaires, vous aurez avantage à utiliser les fonctionnalités les plus récentes de HTML5. Voir par exemple http://www.w3schools.com/html/html_form_elements.asp.

Lorsque l’utilisateur clique sur ‘Envoyer’ la fonction ecrit() est appellée. Vous allez devoir écrire cette fonction.

Vous devez récupérer le contenu de l’élément d’id laPhrase.

Voilà une fonction minimale que vous allez rajouter dans votre script et qui vous permet de vérifier que vous récupérez le texte saisi:

Par exemple, pour trouver, vous faites la recherche google ‘jquery value of input form’ et vous trouvez vite des réponses possibles.

Ici, nous utilisons le selecteur #laPhrase pour récupérer le champs dont c’est l’id et on récupère avec val() la valeur de ce champs de formulaire.

Puis vous le passerez en paramètre d’un appel ajax à une URL de code PHP sur le modèle suivant

Chat.php ?message= »j’ai rien à dire »

La fonction ecrit devient

 

Vous devez écrire le code de chat.php. Faites une version de base qui récupère la valeur du paramètre message et la renvoie à l’appelant.

Cherchez sur Google ‘récupération parametres url php. le premier lien contient des explications sur OpenClasRoom, le deuxième la documentation PHP (http://php.net/manual/fr/reserved.variables.get.php). Vous trouverez vite que la fonction prédéfinie GET vous donne ça avec la syntaxe

pour récupérer le paramètre message.

Le code PHP complet pour récupérer puis renvoyer est

C’est fait : vous avez envoyé un message du client vers le serveur.

Bonus

Dans le code de chat.php, récupérez le paramètre message, ouvrez le fichier message.txt en mode append (fonction fopen avec le mode « a ») et écrivez-y le message que vous venez de récupérer, puis fermez le fichier.

Cela vous donne

fopen ouvre le fichier. fwrite en mode append ajoute le contenu de la variable $chaine à la fin du fichier. fclose ferme le fichier.

Regardez ce qui se passe côté client.

Avec le script complet suivant (ce que nous avons construit dans ce qui précède) 

Si vous ouvrez cette même page dans plusieurs navigateurs, vous avez une communication de base entre utilisateurs de cette page.

Variante avec  JSON

Au lieu du fichier mairie-09001-01.xml, vous allez utiliser le fichier mairie-09001-01.json, écrit dans une syntaxe compatible avec Javascript.

Récupérez le fichier ici, en remplaçant le préfixe xml par json

http://perso.telecom-paristech.fr/~moissina/CPD/TPAjax/data/mairie-09001-01.json

Mettez-le dans un sous-dossier data de votre dossier de travail, afin de se rapprocher de bonnes pratiques (les données dans un dossier data, les scripts dans un dossier js…).

On pourrait utiliser la fonction ajax de jQuery comme précédemment, mais on va plutôt découvrir la fonction getJSON de jQuery.

Voyez ce que ça donne dans un dérivé des codes des étapes précédentes.

Voilà une copie du premier code ajax qui fonctionnait, un peu modifiée pour tenir compte de la documentation du getJSON.

On trouve sur la page de la documentation un exemple de code qui utilise done.

Lorsqu’on charge la page, la boite d’alerte nous montre que la variable data est de type Object javascript.

Une autre variante du code nous montrerait le détail du contenu. J’ai fait une recherche Google ‘string from js Object’. Comme souvent dans les premiers liens, je trouve une question sur stackoverflow qui ressemble à la mienne. Je trouve dans les réponses qu’on peut utiliser JSON.stringify pour transformer un objet javascript en chaîne caractère JSON.

Maintenant, nous avons un objet javascript nommé data dont nous pouvons tirer des informations. Si on met un point d’arrêt sur la ligne alert dans les outils de développement, on peut voir les données obtenues de trois façons:

  • lorsqu’on est arrêté sur la ligne une ligne dans la fonction (ici, il n’y en a qu’une: celle avec alert) en laissant de façon prolongée la souris au dessus de la variable data, on visualise sa valeur
  • en allant dans la colonne de droite sur la partie Watch, avec un clic sur +, on peut ajouter une expression dont on veut voir la valeur courante; on tape data et on peut parcourir l’objet data,
  • en allant un peu plus bas, sur la partie Scope, la sous-partie Local, on peut voir les variables qui existent à l’endroit où on est arrêté; ici on voit data et this; on peut parcourir l’objet data

Maintenant, on peut injecter des choses dans notre page, en exploitant les données figurant dans data. On peut s’inspirer des choses faites avec les données XML.

 

 

Voilà, suivant ce que vous faites, vous pourrez utiliser des données en JSON ou en XML.

Par exemple:

  • structurer des données de votre application en JSON ou XML, et les utiliser pour générer des pages de votre site à partir de ces données,
  • faire une requête à une base de données en demandant une réponse XML (beaucoup de bases le permette) et exploiter ces données dans vos pages,
  • vous servir de données issues de l’Open Data (par exemple, récupérées sur data.gouv.fr) pour enrichir vos pages: liste des mairies, des musées, des pharmacies,…
  • exploiter des web services qui fournissent des réponses en XML ou JSON, comme geonames

Auteur : Moissinac

Maitre de conférence à Télécom ParisTech, Département Signal et Image, Groupe Multimédia Jean-Claude Moissinac mène des recherches sur les techniques avancées pour la production, le transport, la représentation et l’utilisation des documents multimédia. Principaux axes de recherche actuel : représentations sémantiques, adaptation de documents multimédias à des contextes variés d’utilisation ; utilisation du multimédia pervasif

Commentaires Clos.