Contactez-nous

En-têtes HTTP (headers)

Decouvrez le role essentiel des en-tetes HTTP (headers) dans la communication web et apprenez a les lire (req.headers) et les definir (res.setHeader) en Node.js.

Headers HTTP : les metadonnees de la communication web

Au-delà de l'URL demandée, de la méthode utilisée et du corps éventuel du message, une partie cruciale de toute requête et réponse HTTP réside dans ses en-têtes (ou headers). Les en-têtes sont des paires clé-valeur qui transportent des métadonnées essentielles sur la requête elle-même, sur le client qui l'envoie, sur la ressource demandée, sur le serveur qui répond, et sur la réponse fournie.

Ils agissent comme des instructions ou des informations contextuelles qui permettent au client et au serveur de mieux communiquer et de prendre des décisions appropriées. Par exemple, un en-tête peut indiquer le type de contenu que le client accepte, le type de contenu que le serveur renvoie, comment gérer la mise en cache, comment s'authentifier, ou si une redirection est nécessaire.

En Node.js, le module `http` fournit un accès facile à ces en-têtes, à la fois pour lire ceux envoyés par le client dans l'objet `request` et pour définir ceux à envoyer au client dans l'objet `response`.

Lire les en-tetes de la requete (`req.headers`)

Lorsqu'un client (navigateur, application mobile, autre service) envoie une requête HTTP à votre serveur Node.js, il inclut divers en-têtes. Ces en-têtes sont accessibles via la propriété `req.headers` de l'objet `request`. Cette propriété contient un objet JavaScript où les clés sont les noms des en-têtes et les valeurs sont leurs contenus.

Important : Node.js normalise automatiquement les noms des en-têtes entrants en minuscules pour faciliter leur accès, quelle que soit la casse utilisée par le client.

Quelques en-têtes de requête courants et utiles :

  • `host` : Le nom de domaine (et éventuellement le port) du serveur auquel la requête est destinée (ex: `'www.example.com'`, `'localhost:3000'`). Essentiel pour les serveurs hébergeant plusieurs sites (hôtes virtuels).
  • `user-agent` : Une chaîne identifiant le type de client effectuant la requête (ex: navigateur et sa version, `curl`, librairie HTTP spécifique). Utile pour les statistiques ou pour adapter la réponse.
  • `accept` : Indique les types de médias (MIME types) que le client est capable de comprendre et préfère recevoir (ex: `'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'`). Le serveur peut utiliser cette information pour choisir le format de réponse le plus approprié (négociation de contenu).
  • `accept-language` : Indique les langues préférées par l'utilisateur (ex: `'fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7'`). Utile pour la localisation du contenu.
  • `accept-encoding` : Indique les algorithmes de compression que le client supporte (ex: `'gzip, deflate, br'`). Permet au serveur de compresser la réponse pour économiser de la bande passante.
  • `content-type` : (Présent principalement pour POST, PUT, PATCH) Spécifie le type de média du corps de la requête (ex: `'application/json'`, `'application/x-www-form-urlencoded'`, `'multipart/form-data'`). Indispensable pour savoir comment parser le corps de la requête.
  • `content-length` : (Présent si `content-type` l'est) La taille du corps de la requête en octets.
  • `authorization` : Contient les informations d'authentification du client (ex: `'Bearer '`, `'Basic '`).
  • `cookie` : Contient les cookies précédemment envoyés par le serveur et stockés par le client.
  • `referer` (ou `referrer`) : L'URL de la page depuis laquelle la requête a été initiée (si l'utilisateur a cliqué sur un lien).

Exemple d'accès aux headers :

// ... dans http.createServer((req, res) => { ...

  console.log('--- En-têtes de la requête reçue ---');
  console.log('Host:', req.headers['host']);
  console.log('User-Agent:', req.headers['user-agent']);
  console.log('Accept:', req.headers['accept']);

  const contentType = req.headers['content-type'];
  if (req.method === 'POST' && contentType === 'application/json') {
    console.log('Requête POST avec du JSON détectée.');
    // Procéder à la lecture et au parsing du corps...
  }

// ... reste du code ...

Definir les en-tetes de la reponse (`res.setHeader()` / `res.writeHead()`)

Tout comme le client envoie des en-têtes, votre serveur doit en définir dans sa réponse pour fournir des informations essentielles au client sur la nature et le traitement de cette réponse.

Vous pouvez définir les en-têtes de deux manières principales avant que le corps de la réponse ne soit envoyé :

  1. Individuellement avec `res.setHeader(name, value)` : C'est la méthode la plus flexible. Vous appelez cette méthode pour chaque en-tête que vous souhaitez définir. Le `name` est insensible à la casse, mais il est courant de l'écrire en casse mixte standard (ex: `'Content-Type'`). La `value` est généralement une chaîne, mais peut être un tableau de chaînes pour les en-têtes autorisant plusieurs valeurs (comme `Set-Cookie`).
  2. En groupe avec `res.writeHead(statusCode, [statusMessage], [headers])` : Cette méthode envoie la ligne de statut (code + message) et tous les en-têtes fournis dans l'objet `headers` en une seule fois. C'est pratique pour définir plusieurs en-têtes au moment d'envoyer la ligne de statut.

Important : Vous ne pouvez définir les en-têtes que avant que la réponse ne soit envoyée au client. Une fois que `res.writeHead()` a été appelée ou que le premier `res.write()` ou `res.end()` a eu lieu, les en-têtes sont envoyés et ne peuvent plus être modifiés. La propriété `res.headersSent` (booléen) vous indique si les en-têtes ont déjà été envoyés.

Quelques en-têtes de réponse courants :

  • `Content-Type` : Indique le type MIME du corps de la réponse (ex: `'text/html; charset=utf-8'`, `'application/json'`, `'image/png'`, `'text/css'`). Probablement l'en-tête le plus important à définir correctement.
  • `Content-Length` : La taille du corps de la réponse en octets. Bien que non strictement obligatoire (surtout avec le chunked encoding), le fournir aide le client à suivre la progression du téléchargement.
  • `Location` : Utilisé avec les codes de statut 3xx pour indiquer l'URL vers laquelle le client doit être redirigé.
  • `Cache-Control` : Fournit des directives de mise en cache (ex: `'no-cache'`, `'public, max-age=3600'`).
  • `Expires` : Une date indiquant quand la réponse est considérée comme obsolète (ancienne méthode de cache).
  • `Set-Cookie` : Demande au client de stocker un cookie (ex: `'sessionId=abcxyz; HttpOnly; Path=/'`).
  • `Content-Encoding` : Si vous compressez la réponse (ex: avec gzip), cet en-tête indique l'algorithme utilisé (ex: `'gzip'`).
  • `Access-Control-Allow-Origin` : Essentiel pour CORS (Cross-Origin Resource Sharing), permet aux requêtes provenant d'origines différentes (autres domaines) d'accéder à la ressource.

Exemple de définition d'en-têtes :

// ... dans http.createServer((req, res) => { ...

if (req.url === '/json-data') {
  const data = { id: 1, name: 'Example' };
  const jsonData = JSON.stringify(data);

  // Définir les headers avant d'envoyer
  res.setHeader('Content-Type', 'application/json');
  res.setHeader('X-Custom-Header', 'Ma valeur perso');
  res.setHeader('Content-Length', Buffer.byteLength(jsonData));

  res.statusCode = 200;
  res.end(jsonData); // Les headers sont envoyés implicitement ici

} else if (req.url === '/redirect') {
  // Utilisation de writeHead pour statut et headers
  res.writeHead(302, { // 302 Found (redirection temporaire)
    'Location': '/target-page',
    'Cache-Control': 'no-cache'
  });
  res.end(); // Pas de corps nécessaire

} else {
  // ...
}
// ... fin du listener ...

Conclusion : un dialogue structure

Les en-têtes HTTP sont bien plus que de simples détails techniques ; ils constituent un langage essentiel qui structure le dialogue entre les clients et les serveurs web. Ils permettent la négociation de contenu, la gestion de l'état (cookies), l'authentification, le contrôle du cache, et bien d'autres fonctionnalités fondamentales.

En Node.js, savoir lire les `req.headers` pour comprendre la demande du client et savoir définir correctement les en-têtes de la réponse avec `res.setHeader` ou `res.writeHead` est indispensable pour construire des applications web robustes, efficaces et conformes aux standards du web.