Node.js - Du Javascript coté serveur

Auteur: Mohamed CHINY Durée necessaire pour le cours de Node.js - Du Javascript coté serveur Niveau recommandé pour le cours de Node.js - Du Javascript coté serveur Supports vidéo disponibles pour ce cours Exercices de renforcement non disponibles pour ce cours Quiz non disponibles pour ce cours

Page 4: Envoyer des entêtes et formater le rendu HTML

Toutes les pages

Envoyer les entêtes HTTP en Node.js

Spécifier l'encodage (ou jeu de caractères) à l'aide writeHead()

Reprenons le code de la dernière fois:
const http=require("http")

http.createServer((req,res)=>{
   res.write("Réponse envoyée au client")
   res.end()
}).listen(8080,()=>{
   console.log("Serveur en écoute...")
})
J'ai fait en sorte d'utiliser les deux méthodes write() et end() au lieu d'utiliser que la méthode end() toute seule.

Après exécution, on obtient le résultat suivant sur le navigateur:
Réponse envoyée au client
Comme vous le voyez, les accents sont mal affichés et ça sera le cas pour les autres caractères spéciaux ou tout caractère alphabétique qui provient d'un système d'écriture plus complexe que le latin. Ce problème vient de l'encodage. En effet, le serveur HTTP devrait envoyer des entêtes au navigateur pour l'informer de la nature du contenu attendu, en l'occurrence le jeu de caractère que le navigateur doit utiliser pour mieux afficher le texte reçu.

Dans les serveurs Web classiques (comme Apache, Nginx, IIS...), les entêtes sont automatiquement envoyés avec des valeurs par défaut spécifiés par l'administrateur système au moment de la configuration du serveur. En Node.js, c'est le développeur qui doit formuler ces entêtes-là dans le code Javascript à l'aide de la méthode writeHead() de l'objet réponse (ou res dans l'exemple).

Le code ressemblera à ceci:
const http=require("http")

http.createServer((req,res)=>{
   res.writeHead(200,{
      "content-type":"text/html;charset=UTF-8"
   })
   res.write("Réponse envoyée au client")
   res.end()
}).listen(8080,()=>{
   console.log("Serveur en écoute...")
})
La méthode writeHead() se charge d'envoyer des entêtes au navigateur y compris le code HTTP correspondant en guise de premier argument (dans ce cas le code 200 pour indiquer OK). Le deuxième argument est un objet Javascript littéral qui peut contenir autant d'entêtes que l'on souhaite. Dans ce cas, nous avons spécifié l'entête content-type qui a comme valeur text/html; charset=UTF-8, ce qui veut dire que le contenu attendu par le client est du code HTML (qui est du texte), et le jeux de caractères à utiliser pour afficher ce texte-là est l'UTF-8 qui prend en charge tous les caractères existants.

Après exécution on obitent:
Réponse envoyée au client
Les accents sont désormais affichés correctement.
Notez qu'il est également possible d'envoyer des entêtes à l'aide de la méthode setHeader() de l'objet réponse. La différence avec writeHead() c'est que cette dernière doit être appelée une seule fois avant la fin du processus réponse (appel de la méthode end()), alors que setHeader() peut être appelée autant de fois que nécessaire et contient deux argument: la nature de l'entête et sa valeur. Exemple: res.setHeader("content-type","text/html; charset=UTF-8")

Envoyer un document HTML formaté en guise de réponse de Node.js

Module FS (ou File System) de Node.js

Node.js offre la possibilité d’interagir avec le système de fichiers (espace de stockage) qui supporte le serveur. A cet effet, le module nommé fs (pour File System) doit être inclus au début du fichier server.js au même titre que le module http comme ceci:
const http=require("http")
const fs=require("fs")
Désormais, il est possible aux scripts de Node.js d’accéder aux fichiers du serveur, c'est à dire, ils peuvent mener les opérations suivantes:
  • Lecture des fichiers
  • Modifier le contenu des fichiers
  • Créer de nouveaux fichiers
  • Renommer les fichiers
  • Supprimer les fichiers

Accéder à un fichier HTML est le présenter en tant que réponse du serveur

Commençons par créer un document HTML que l'on enregistre dans le même répertoire que server.js. On nommera notre document HTML index.html et il contiendra le code suivant:
<!DOCTYPE html>
<html>
   <head>
      <meta charset="utf-8" />
      <title>Node.js</title>
   </head>
   <body>
      <h1>Bonjour</h1>
      <p>Page retournée par un serveur <b>Node.js</b></p>
   </body>
</html>
Dans le fichier server.js on va écrire le code suivant:
const http=require("http")
const fs=require("fs")

http.createServer((req,res)=>{
   fs.readFile("index.html",(err,data)=>{
      if(err){
         res.writeHead(404)
         res.write("Page introuvable!")
      }
      else{
         res.writeHead(200,{
            "content-type":"text/html;charset=UTF-8"
         })
         res.write(data)
      }
      res.end()
   })
}).listen(8080,()=>{
   console.log("Serveur en écoute...")
})
Ce qui est nouveau dans ce code, c'est l'invocation de la méthode readFile() qui accepte comme premier argument l'emplacement du fichier à lire (index.html dans ce cas) et, comme deuxième argument, une fonction de rappel qui a aussi deux arguments err et data qui représentent respectivement toute erreur éventuelle au moment de l'ouverture du fichier (comme le fait que le fichier n'existe pas ou ne soit pas accessible) et le contenu du fichier. Bien entendu, on peut nommer ces deux arguments comme on le souhaite.
Il est parfois nécessaire d'intercaler l'argument "utf-8" à la méthode readFile() entre le chemin du fichier et la fonction de rappel pour éviter les erreurs liés à l'encodage.
Le traitement que nous avons vu avant doit désormais être placé dans le corps de la fonction de rappel passée à la méthode readFile(). En effet, on vérifie si une erreur a été signalée, dans ce cas, on envoie un code HTTP 404 qui indique que la ressource cherchée est introuvable, puis on affiche le message Page introuvable!. Sinon, dans ce cas on envoie le code HTTP 200 en indiquant l'encodage qui correspond au HTML, puis on affiche le contenu du fichier. Dans tous les cas, on met fin au processus de réponse à l'aide de la méthode end().

Si tout se passe comme prévu, on aura ceci sur le navigateur:

Bonjour

Page retournée par un serveur Node.js

Notez que vous pouvez envoyer n'importe quel code d'erreur en cas d'échec, comme les codes HTTP de la famille 500 qui signifient "Erreur interne du serveur".
Pour pouvez ajouter des styles CSS exactement comme vous le faisiez avant.
Il est possible d'ajouter d'autres entêtes pour prendre en compte l'existence de serveurs mandataires ou Proxy en amont du client.

Envoyer les entêtes HTTP et formater le rendu HTML en vidéo