Développer aisément en client/serveur

AJAX

1. Requête simple

AJAX (Asynchronous JavaScript and XML) sert à effectuer une requête vers un serveur sans avoir à recharger la page HTML courante. Couplé à la possibilité de modifier dynamiquement une page HTML, cela transforme une page HTML en véritable application.

La requête peut être synchrone (ou bloquante) ou bien asynchrone (la forme la plus courante).

Pour effectuer une requête AJAX, il faut un objet de classe XMLHttpRequest.

Pour des questions de sécurité, la première version de XMLHttpRequest n’autorise que des accès vers le serveur source de la page. Ceci étant parfois peu pratique (obligation de faire du routage vers d’autres serveurs), une deuxième version autorise l’usage de domaines différents mais nécessite des autorisations (CORS pour Cross Origin http RequeSt).

Pour pouvoir intercepter la réponse, vous avez à disposition la propriété onreadystatechange. Cette propriété a pour but d’invoquer la fonction utilisateur fournie lorsqu’une partie ou la totalité de la réponse serveur est retournée. Une propriété supplémentaire readyState sert à connaître l’état d’avancement de la réception de la réponse. Une propriété status sert à connaître le code de réponse du serveur HTTP, utile en cas d’erreur (5XX par exemple pour une erreur interne).

Lorsque l’objet de requête est prêt, il reste à exécuter la requête par la méthode open avec en arguments le type de requête HTTP (GET ou POST), l’URL et un booléen pour savoir si votre requête est bloquante (synchrone) ou non (le plus courant). Enfin, pour l’envoi final, vous utiliserez la méthode send avec en arguments les éventuels paramètres. Comme il s’agit d’une requête HTTP, l’encodage des paramètres est par défaut identique à ce que vous mettez dans une URL, c’est-à-dire sous la forme cle=valeur séparée par &. Si vos valeurs peuvent contenir des caractères réservés comme &, alors il faut faire un encodage avec la fonction encodeURIComponent.

Pour ce premier exemple, nous avons...

Chargement dynamique de script

1. Première implémentation

Comme nous l’avons vu jusqu’ici, la balise script sert à charger un script JavaScript externe. Cette faculté peut être détournée pour émuler une requête auprès d’un serveur et cela sans être limitée par le type d’accès, contrairement à AJAX qui se limite par défaut à un domaine. Le serveur ne va donc pas générer un format JSON en réponse dans ce cas mais bien un format JavaScript.

Pour que la requête fonctionne, il faut créer dynamiquement la demande de chargement. Pour cela, nous recherchons dans la page la balise head, puis nous créons une nouvelle balise script avant d’effectuer l’ajout dans la balise d’en-tête. Grâce à l’attribut onload nous serons notifiés lorsque le chargement du script (et donc la réponse du serveur) sera effectué. C’est ce type de fonctionnement qui est présent avec le chargement de modules AMD (Asynchronous Module Definition). À noter que rien n’interdit d’insérer également la balise script dans le corps de la balise body.

Comme nous demandons un script par une URL, nous sommes donc limités à des requêtes de type GET.

Pour le test, nous avons conçu un fichier émulant la réponse d’un serveur script1.js

const auteur =   
{ nom : "brillant", prenom : "alexandre"  
};  
 
auteur.ouvrages = [  
    { titre : "Ruby",  
    sousTitre...

Promesses

1. Principe

JavaScript a introduit une forme normalisée pour prendre en compte tous les traitements asynchrones (comme une requête AJAX). Ces traitements doivent éviter un blocage du code, et pour cela la norme a introduit un système par abonnement que l’on nomme Promesse. Une promesse est une forme de contrat pour dire que si tel ou tel événement arrive, alors ce traitement devra être exécuté.

Cela se traduit par une classe Promise. Cette classe a un constructeur avec une fonction en argument. Cette fonction a deux arguments, une fonction de traitement utilisateur et une fonction pour gérer l’erreur. Pour résumer l’exécution, la classe Promise invoque cette fonction qui est normalement asynchrone puis utilise les arguments pour effectuer une notification du succès ou non de l’opération.

Dans cet exemple, nous simulons un accès asynchrone avec un timer :

    const promesse = new Promise(  
        ( montraitement,  
          monerreur   
        ) => {  
            setTimeout(   
                () => montraitement(),  
                5000 );  
        }  
    );  
   
    promesse.then(   
        () => {  
            alert( "Le traitement asynchrone est termine !" )  
        }  
    ); 

Nous avons un objet promesse, ce dernier passe donc au constructeur de la classe Promise une fonction anonyme (ici une fonction fléchée). Dans cette fonction, nous avons l’argument montraitement qui est une nouvelle fonction. Elle est ensuite invoquée par le traitement asynchrone avec la fonction setTimeout au bout de 5 secondes.

L’utilisateur de l’objet promesse a besoin de savoir que l’opération asynchrone est terminée...