Requêtes en javascript

On a vu précédemment comment construire du XML, maintenant il reste à effectuer une requête sur le serveur pour aller chercher ce fichier XML.

L'objet XMLHttpRequest

Le javascript met à notre disposition pour celà un objet permettant d'effectuer des requêtes HTTP.

Construction : différents navigateurs ... différentes syntaxes

Toujours le même problème avec javascript : certaines fonctionnalités ne sont pas accessibles de la même manière sous IE ou sous Firefox, ou encore avec Opera. XMLHttpRequest est de ceux qui nécessite de passer par un objet intermédiaire.

var httpObj = null;
if (window.XMLHttpRequest){ //Firefox
	httpObj = new XMLHttpRequest();
}else if (window.ActiveXObject){ // IE
	httpObj = new ActiveXObject('Microsoft.XMLHTTP');
} // Sinon ce n'est pas supporté

Effectuer une requête

Une fois l'objet créé, on peut interroger un serveur.

Attention : on ne peut interroger en JS uniquement des serveurs sur le même domaine que le serveur web sur lequel la page est hébergée.

Par exemple si votre site de test a une adresse http://www.pipo1.com et que votre script veut interroger http://www.tartempion.com ça ne fonctionnera pas

Pour pouvoir faire ce genre de choses, il faut mettre en place un proxy qui peut se faire en PHP pour des besoins de débug.

Exemple :
httpObj.open('GET','http://www.tartempion.com/index.php?id=32&ok=1',false);
httpObj.send(null);
httpObj.open('POST','http://www.tartempion.com/index.php',false);
httpObj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
httpObj.send('id=32&ok=1');
Détail des arguments :
  1. Méthode d'envoi des données : 2 valeurs possibles
    • GET : les données doivent être écrites dans l'adresse, voir l'exemple. Méthode souvent utilisée pour des paramètres numériques en petit nombre.
    • POST : nécessite de signaler explicitement qu'on envoie le résultat d'un formulaire (setRequesHeaders) puis d'envoyer celui-ci avec la méthode send. Utilisé pour les gros formulaires en général, ou pour l'envoi de fichiers.
  2. Adresse à requêter
  3. Requête synchrone
    • true : aucun javascript ne s'exécute tant que la réponse n'est pas arrivée. L'application est bloquée.
    • false : l'application suit son cours. Il faut utiliser l'événement onreadystatechange ou onload pour éxécuter du code à la réception de la réponse.

Important : requête sur un autre domaine

Javascript ne permet pas d'interroger un serveur sur un autre domaine que le site en question. Pour contourner cette limitation,

Récupérer le résultat

Une fois la requête lancée, on aimerai bien connaitre le résultat renvoyé par le serveur pour le traiter. Pour cela, il faut utiliser l'événement onreadystatechange ou onload de l'objet HTTPXmlRequest.

Exemple :
function traitement(){
	// Si la requête est terminée
	if (this.readyState==4)
	{
		// Succes de la requête
		if (this.status>=200 && this.status < 300)
		{
			tout_traiter_XML(this.responseXML);
			// ou
			// tout_traiter_texte(this.responseText);
		}
	}
}
httpObj.open('GET','http://www.tartempion.com/index.php?id=32&ok=1',false);
httpObj.onreadystatechange=traitement();
httpObj.send(null);

Traiter le résultat

Lorsque le XML a été récupéré, on peut le parcourir en utilisant le DOM comme vu précédemment.

On a donc accès à tous les attributs et les méthodes disponibles pour manipuler du XML :

Interface Document

httpObj.responseXML.document
Implémente l'interface Document, décrite sur le site du W3C.
interface Document : Node {
  readonly attribute 	DocumentType     		doctype;
  readonly attribute 	DOMImplementation  		implementation;
  readonly attribute 	Element          		documentElement;
  			Element            		createElement(in DOMString tagName)
                                        			raises(DOMException);
  			DocumentFragment   		createDocumentFragment();
  			Text				createTextNode(in DOMString data);
  			Comment            		createComment(in DOMString data);
  			CDATASection       		createCDATASection(in DOMString data)
		    	                                    	raises(DOMException);
  			ProcessingInstruction		createProcessingInstruction(in DOMString target, 
  											in DOMString data)
                                        			raises(DOMException);
  			Attr               		createAttribute(in DOMString name)
                                        			raises(DOMException);
  			EntityReference    		createEntityReference(in DOMString name)
                                        			raises(DOMException);
  			NodeList           		getElementsByTagName(in DOMString tagname);
  // ---------------
  // Introduced in DOM Level 2:
  			Node               		importNode(in Node importedNode, 
                                			in boolean deep)
                                        			raises(DOMException);
  			Element            		createElementNS(in DOMString namespaceURI, 
                                     			in DOMString qualifiedName)
                                        			raises(DOMException);
  			Attr               		createAttributeNS(in DOMString namespaceURI, 
                                       			in DOMString qualifiedName)
                                        			raises(DOMException);	
			NodeList           		getElementsByTagNameNS(in DOMString namespaceURI, 
                                            		in DOMString localName);
 		 	Element            		getElementById(in DOMString elementId);
};
		

Interface Element

httpObj.responseXML.document.documentElement
Implémente l'interface Element
interface Element : Node {
  readonly attribute	DOMString        		tagName;
  			DOMString          		getAttribute(in DOMString name);
  			void               		setAttribute(in DOMString name, 
							in DOMString value)
								raises(DOMException);
  			void               		removeAttribute(in DOMString name)
								raises(DOMException);
			Attr               		getAttributeNode(in DOMString name);
			Attr               		setAttributeNode(in Attr newAttr)
			                                        raises(DOMException);
			Attr               		removeAttributeNode(in Attr oldAttr)
			                                        raises(DOMException);
			                        // Contient des objets implémentant l'interface Element;
			NodeList           		getElementsByTagName(in DOMString name) 
 //-----------------------
 // Introduced in DOM Level 2:
			DOMString          		getAttributeNS(in DOMString namespaceURI, 
			                        	in DOMString localName);
			void               		setAttributeNS(in DOMString namespaceURI, 
			                            	in DOMString qualifiedName, 
			                            	in DOMString value)
			                                        raises(DOMException);
			void               		removeAttributeNS(in DOMString namespaceURI, 
			                            	in DOMString localName)
			                                        raises(DOMException);
			Attr               		getAttributeNodeNS(in DOMString namespaceURI, 
			                             	in DOMString localName);
			Attr               		setAttributeNodeNS(in Attr newAttr)
			                                        raises(DOMException);
			NodeList           		getElementsByTagNameNS(in DOMString namespaceURI, 
					                	in DOMString localName);
			boolean            		hasAttribute(in DOMString name);
			boolean            		hasAttributeNS(in DOMString namespaceURI, 
			                               	in DOMString localName);
};
		

Interface Node

httpObj.getElementsByTagName('root')[0]
Implémente l'interface Node, tout comme les Elements puisqu'ils dérivent de cette interface
interface Node {

  // NodeType
			const unsigned short      	ELEMENT_NODE                = 1;
			const unsigned short		ATTRIBUTE_NODE              = 2;
			const unsigned short		TEXT_NODE                   = 3;
			const unsigned short		CDATA_SECTION_NODE          = 4;
			const unsigned short		ENTITY_REFERENCE_NODE       = 5;
			const unsigned short		ENTITY_NODE                 = 6;
			const unsigned short		PROCESSING_INSTRUCTION_NODE = 7;
			const unsigned short		COMMENT_NODE                = 8;
			const unsigned short		DOCUMENT_NODE               = 9;
			const unsigned short		DOCUMENT_TYPE_NODE          = 10;
			const unsigned short		DOCUMENT_FRAGMENT_NODE      = 11;
			const unsigned short		NOTATION_NODE               = 12;

  readonly attribute 	DOMString        		nodeName;
           attribute 	DOMString        		nodeValue;
                                        			// raises(DOMException) on setting
                                       			 	// raises(DOMException) on retrieval

  readonly attribute 	unsigned short   		nodeType;
  readonly attribute 	Node             		parentNode;
  readonly attribute 	NodeList         		childNodes;
  readonly attribute 	Node             		firstChild;
  readonly attribute 	Node             		lastChild;
  readonly attribute 	Node             		previousSibling;
  readonly attribute 	Node             		nextSibling;
  readonly attribute 	NamedNodeMap     		attributes;
  
  // Modified in DOM Level 2:
  readonly attribute 	Document         		ownerDocument;
  			Node               		insertBefore(in Node newChild, 
                                  			in Node refChild)
                                        			raises(DOMException);
			Node               		replaceChild(in Node newChild, 
			                                in Node oldChild)
			                                        raises(DOMException);
			Node               		removeChild(in Node oldChild)
			                                        raises(DOMException);
			Node               		appendChild(in Node newChild)
			                                        raises(DOMException);
			boolean            		hasChildNodes();
			Node               		cloneNode(in boolean deep);
  // Modified in DOM Level 2:
  			void               		normalize();
  
  //----------------------------
  // Introduced in DOM Level 2:
  
  			boolean            		isSupported(in DOMString feature, 
                                 			in DOMString version);
  readonly attribute 	DOMString        		namespaceURI;
           attribute 	DOMString        		prefix;
                                        			// raises(DOMException) on setting
  readonly attribute 	DOMString        		localName;
  			boolean            		hasAttributes();
};

Les informations exhaustives se trouvent sur le site du W3C.