Compléments de PHP Requêtes asynchrones et AJAX Technologies côté client * HTML: HyperText Markup Language * Structuration de l'information * CSS: Cascade Style Sheet * Feuille de style * Présentation de l'information * DOM: Document Object Model * Modèle objet du document * Représentation de tous les éléments du document (HTML + CSS) * JavaScript * Gestion des événements du document * Modification dynamique du document DHTML et AJAX * Ne sont pas des technologies à proprement parlé * Regroupent un ensemble de technologies * DHTML: Dynamic HTML * Regroupe plusieurs technologies pour le dynamisme des pages Web * HTML + CSS + DOM + JavaScript * AJAX: Asynchronous JavaScript And XML * Propose en plus un mécanisme asynchrone de communication * DHTML + Asynchrone + XML * Asynchrone * Possibilité de requêtes non visibles avec un serveur * XML * Manipulation de données structurées Communication asynchrone (1/2) * JavaScript peut communiquer avec un serveur * Possibilité de transmettre des variables * Méthodes "get" et "post" * Une page PHP peut donc recevoir ces informations * La page PHP peut aussi répondre et transmettre des données * JavaScript peut lire des données XML * Ces données peuvent provenir d'un fichier local ou distant * Elles peuvent aussi provenir du résultat d'une page PHP * Possibilité d'effectuer une requête dans une base de données * Récupération au format XML du résultat Communication asynchrone (2/2) La classe "XMLHttpRequest" (1/3) * Pour communiquer: la classe "XMLHttpRequest" * hreq = new XMLHttpRequest(); * Certains navigateurs n'ont pas cette classe directement * Utilisation du mécanisme d'ActiveX (Microsoft) * hreq = new ActiveXObject("Microsoft.XMLHTTP"); * En revanche, l'API (les fonctionnalités) est la même * Code "portable" var hreq = null; if (window.XMLHttpRequest) hreq = new XMLHttpRequest(); else if (window.ActiveXObject) hreq = new ActiveXObject("Microsoft.XMLHTTP"); if (hreq == null) alert("XMLHttpRequest non supporté !"); else { // OK, communication possible } La classe "XMLHttpRequest" (2/3) * Pour effectuer une requête sur un serveur: méthodes "open" et "send" * JavaScript accède à la page indiquée * hreq.open("méthode","adresse",true); * Méthode = "GET" ou "POST" * Adresse = URL de la page à ouvrir * Des variables peuvent être transmises * Utilisation du format "get" variables = "nom=Nawouak&mdp=12345"; * Avec méthode "get" hreq.open("GET","http://localhost/login.php?"+variables,true); hreq.send(null); * Avec méthode "post" hreq.open("POST","http://localhost/login.php",true); hreq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); hreq.send(variables); La classe "XMLHttpRequest" (3/3) * JavaScript n'attend pas la fin de "send" pour continuer son exécution * D'où le terme "asynchrone" * Il faut donc un mécanisme d'écouteur * Changement d'état dans la communication ==> appel de la méthode "onreadystatechange" * Accès à l'état: hreq.readyState * hreq.readyState == 4 ==> communication terminée * Exemple (à placer avant "send") hreq.onreadystatechange = function() { if (hreq.readyState == 4) { var reponse = hreq.responseText; ==> réponse format texte ou var reponse = hreq.responseXML; ==> réponse format XML ... } } Retour des informations * Réponse simple ==> retourner du texte * Simple oui / non * Quelques valeurs * Exemple de format texte * Après vérification des identifiants, on retourne validité + ID * echo "$valide:$id"; ==> oui:27 * Récupération par JavaScript du texte * Découpage en morceaux * var reponse = hreq.responseText.split(":"); var valide = reponse[0]; var id = reponse[1]; * Réponse structurée ==> retourner du XML * Résultat d'une requête dans une base de données Exemple de dialogue simple * Exemple PHP: vérification des identifiants <?php header("Content-Type: text/html; charset=iso-8859-1"); $login = $_GET["login"]; $pass = $_GET["pass"]; ... // Requête pour vérifier la validité des identifiants, ... // et récupération de l'ID. if ($valide) echo "oui:$id"; else echo "non:0"; ?> * Code JavaScript associé hreq.onreadystatechange = function() { if (hreq.readyState == 4) { var reponse = hreq.responseText.split(":"); var valide = reponse[0]; var id = reponse[1]; ... // Poursuite du code ici ! } } variables = "nom=Nawouak&mdp=12345"; hreq.open("GET","http://localhost/login.php?"+variables,true); hreq.send(null); Récupérer un document XML * Récupération d'un document XML suite à "send" * var reponse = hreq.responseXML; * Document XML = hiérarchie de noeuds * Parcourir la hiérarchie des noeuds * n.firstChild: premier sous-noeud du noeud n * n.childNodes: tableau des sous-noeuds du noeud n * n.childNodes[i]: ième sous-noeud du noeud n * n.childNodes.length: nombre de sous-noeuds de n * Accéder aux données * n.attributes: tableau des attributs du noeud n * n.attributes.attr: valeur de l'attribut "attr" du noeud n * n.nodeValue: valeur du noeud n, si celui-ci est un noeud texte * n.nodeName: nom de balise du noeud n, si celui-ci est une balise * Parcours fonctionnant aussi pour HTML ! Exemple de langage formulé avec XML <?xml version="1.0" encoding="ISO-8859-1"?> <biblio> <ouvrage type="thriller"> <titre>Dragon rouge</titre> <auteur>Harris, Thomas</auteur> </ouvrage> <ouvrage type="science fiction"> <titre>Contact</titre> <auteur>Sagan, Carl</auteur> </ouvrage> <ouvrage type="roman"> <titre>Et si c'était vrai</titre> <auteur>Lévy, Marc</auteur> </ouvrage> </biblio> Structure hiérarchique d'un document XML Exemple de récupération XML * Données XML retournées par PHP <reponse valide="oui"> ... <id>27</id> </reponse> * Parcours de l'arbre XML avec JavaScript var reponse = hreq.responseXML; var valide = ""; var id = ""; var noeud = reponse.firstChild; if (noeud.nodeName == "reponse") { valide = noeud.attributes.valide; var fils = noeud.childNodes; for (var i = 0; i < fils.length(); i++) { if (fils[i].nodeName == "id") id = fils[i].firstChild.nodeValue; } } else alert("Problème !"); Modifier un code HTML (1/3) * Première solution: "innerHTML" var zone = document.getElementById("message"); zone.innerHTML = "<p>Réponse:</p>"; zone.innerHTML += "<ul><li>valide = " + valide + "</li><li>id = " + id + "</li></ul>"; * Ne marche pas toujours ! * Sur certains navigateurs * Pour certaines balises * Autre solution: utiliser la création de noeuds du DOM * Comme pour le parcours d'un arbre HTML, il existe des méthodes pour modifier l'arbre Modifier un code HTML (2/3) * Attention aux mélanges ! * Soit vous utilisez "innerHTML" * Soit vous utilisez la création de noeuds du DOM * Effacer le contenu d'un noeud * Avec "innerHTML" zone.innerHTML = ""; * Avec le DOM while (zone.childNodes.length > 0) { zone.removeChild(zone.firstChild); } Modifier un code HTML (3/3) * Avec le DOM, création des éléments un par un * document.createElement("nawouak"); * Crée un noeud balise <nawouak> * Pour l'instant, il n'est pas placé dans le code HTML * document.createTextNode("bla bla bla"); * Crée un noeud texte "bla bla bla" * Pour l'instant, il n'est pas placé dans le code HTML * nx.appendChild(ny); * Ajoute le noeud ny (balise ou texte) dans le noeud nx * L'insertion dans le code HTML est effective à ce moment * nx.setAttribute("style","color:blue") * Ajoute l'attribut style="color:blue" au noeud nx Exemple de création de noeuds HTML * Version "innerHTML" zone.innerHTML = "<p>Réponse:</p>"; zone.innerHTML += "<ul><li>valide = " + valide + "</li><li>id = " + id + "</li></ul>"; * Version DOM var paragraf = document.createElement("p"); var liste = document.createElement("ul"); var item1 = document.createElement("li"); var item2 = document.createElement("li"); paragraf.appendChild(document.createTextNode("Réponse:")); item1.appendChild(document.createTextNode(valide = " + valide)); item2.appendChild(document.createTextNode(id = " + id)); liste.appendChild(item1); liste.appendChild(item2); zone.appendChild(paragraf); zone.appendChild(liste); |