Lesson 5/8 12 min

Request, response, status codes

The HTTP request read line by line like a letter, the methods, the response and its status codes. Learn to read the postman's stamps.

Enfin, on parle

À la leçon 4, le canal sécurisé s'est ouvert. Le DNS a donné l'adresse, TLS a posé la poignée de main chiffrée, et maintenant le tuyau est prêt. Mais un tuyau ouvert ne dit rien tout seul. Il faut envoyer quelque chose dedans.

Ce quelque chose, c'est une lettre. Ton navigateur écrit une lettre, la glisse dans le canal, et le serveur répond par une autre lettre. C'est tout HTTP : un échange de lettres. Une lettre de demande (la requête), une lettre de réponse (la réponse).

Et comme toute lettre, elle a une structure : une adresse, une enveloppe couverte d'annotations, et un contenu. Apprends à lire cette lettre, et le web n'a plus de secret. Tu sauras pourquoi un site répond « 404 », ce que veut dire « 301 », et où chercher quand ça casse. On commence par la lettre de demande.

La lettre de demande, ligne par ligne

Voici une vraie requête HTTP, telle qu'elle circule dans le canal. Brute, sans maquillage. Lis-la une fois, puis on décortique chaque ligne :

GET /produits/chaussures?taille=42 HTTP/1.1
Host: www.boutique.fr
User-Agent: Mozilla/5.0 ...
Accept: text/html
Cookie: session=abc123

La première ligne est la plus importante : c'est la ligne de requête. Elle dit trois choses, dans l'ordre.

  • GET : la méthode. Ici, « je veux lire ». On y revient juste après.
  • /produits/chaussures?taille=42 : le chemin et la query string. Souviens-toi de la leçon 2 : ce morceau vient directement de l'URL. Le navigateur a découpé l'URL et a posé ici sa partie « chemin ».
  • HTTP/1.1 : la version du protocole utilisée pour cette lettre.

Les lignes suivantes sont les headers : les annotations sur l'enveloppe. Chacune renseigne le serveur sur le contexte de la demande. Il en existe des dizaines, mais voici les quelques-uns qui comptent vraiment :

  • Host : le seul header obligatoire en HTTP/1.1. Pourquoi ? Parce qu'un même serveur, à une même adresse IP, héberge souvent des centaines de sites différents. Le canal te connecte à la machine, mais la machine a besoin de savoir quel site tu cherches. Sans Host, elle ne sait pas quelle porte ouvrir.
  • User-Agent : ta carte de visite. Quel navigateur, quel système. Le serveur peut s'en servir pour adapter sa réponse (ou pour des statistiques).
  • Accept : ce que tu sais recevoir. Ici text/html : « envoie-moi du HTML ». Une API répondrait plutôt Accept: application/json.
  • Cookie : un petit jeton que le navigateur renvoie à chaque visite. Ici session=abc123. Garde ce mot en tête : c'est la graine de la leçon 6, celle qui explique comment le site se souvient de toi.

Côté envoi : quand tu envoies des données (un formulaire, un fichier), un header de plus apparaît : Content-Type. Il annonce le format du contenu que tu joins, par exemple application/json ou application/x-www-form-urlencoded. Il sert au serveur à savoir comment lire ce que tu lui glisses dans l'enveloppe.

Les méthodes : quatre verbes pour quatre intentions

La méthode, c'est le verbe en tête de la lettre. Il annonce ton intention. Quatre suffisent à couvrir l'essentiel :

  • GET : lire. Tu demandes une ressource, sans rien changer. Ouvrir une page, charger une image, consulter une fiche produit.
  • POST : créer ou envoyer. Tu transmets des données qui produisent un effet : poster un commentaire, valider un panier, créer un compte.
  • PUT : remplacer. Tu écrases une ressource existante par une nouvelle version complète.
  • DELETE : supprimer. Tu demandes l'effacement d'une ressource.

Un mot sur l'idempotence, qui a l'air savant mais tient en deux phrases. Rejouer une requête GET, PUT ou DELETE laisse le serveur dans le même état : lire deux fois ne change rien, supprimer deux fois donne le même « c'est supprimé ». Rejouer un POST, en revanche, crée un doublon : valide deux fois ton panier, et tu as deux commandes. C'est pour ça que le navigateur t'avertit avant de « renvoyer le formulaire ».

Rappel : tu as croisé ces verbes dans le cours PHP, avec les formulaires. Un <form method="get"> envoie une requête GET (les champs partent dans la query string de l'URL), un <form method="post"> envoie un POST (les champs partent dans le body). C'est exactement la même mécanique, vue ici depuis le réseau.

La lettre de réponse, et son tampon

Le serveur a lu ta lettre. Il répond par la sienne. Même logique, structure miroir :

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 1834
Set-Cookie: session=abc123

<!DOCTYPE html>
<html> ... </html>

Décorticons :

  • La ligne de statut (HTTP/1.1 200 OK) : c'est le tampon de la lettre. Le code 200 et son libellé OK disent en un coup d'œil comment ça s'est passé. C'est la première chose qu'on lit.
  • Les headers : Content-Type annonce le format du contenu renvoyé (du HTML en UTF-8), Content-Length donne sa taille en octets, et Set-Cookie demande au navigateur de mémoriser un cookie. Encore cette graine de la leçon 6 : remarque que le serveur pose le cookie avec Set-Cookie, et que le navigateur le renverra ensuite avec Cookie.
  • La ligne vide : elle sépare les headers du contenu. C'est le pli de l'enveloppe. Tout ce qui suit est le corps.
  • Le body : le contenu. Ici, le HTML de la page. Pour une API, ce serait du JSON. Pour une image, des octets bruts.

Les status codes : quatre familles, pas une liste à apprendre

Il existe une soixantaine de status codes. Personne ne les connaît tous par cœur, et c'est inutile. Le secret, c'est de retenir les familles, c'est-à-dire le premier chiffre. Une phrase mnémo suffit :

« 2xx ça marche, 3xx c'est ailleurs, 4xx c'est toi, 5xx c'est lui. »

« Toi », c'est le client (ton navigateur). « Lui », c'est le serveur. Avec ce réflexe, tu sais déjà de quel côté chercher avant même de lire le détail. Voici les huit codes qui couvrent 95 % de ta vie de dev :

  • 200 OK : tout s'est bien passé, voici ce que tu as demandé.
  • 301 vs 302 : deux redirections. Le 301 est définitif (« cette page a déménagé pour toujours, mémorise la nouvelle adresse »), le 302 est temporaire (« va voir ailleurs pour l'instant, mais reviens ici plus tard »). La nuance compte pour le SEO, on y revient au quiz.
  • 304 Not Modified : « rien n'a changé depuis ta dernière visite, garde ta version ». Graine de la leçon 7 sur le cache.
  • 400 Bad Request : ta lettre est mal formée, le serveur ne la comprend pas.
  • 401 vs 403 : deux refus, mais pas pour la même raison. 401 Unauthorized = « je ne sais pas qui tu es, identifie-toi ». 403 Forbidden = « je sais qui tu es, et tu n'as pas le droit ». Pas identifié contre identifié-mais-interdit.
  • 404 Not Found : la ressource demandée n'existe pas. Le grand classique.
  • 500 Internal Server Error : le serveur a planté en traitant ta demande. Le bug est chez lui.
  • 503 Service Unavailable : le serveur est temporairement débordé ou en maintenance. Reviens plus tard.

Le premier chiffre te dit déjà OÙ chercher le bug. Un 4xx ? Regarde ce que ton client envoie : mauvaise URL, données invalides, droits manquants. Un 5xx ? Inutile de fouiller ta requête, le problème est côté serveur : logs, base de données, code planté. Avant de plonger dans les détails, lis le premier chiffre. Il t'épargne la moitié des recherches inutiles.

Les deux lettres, côte à côte

Garde cette image en tête : à gauche la lettre de demande, à droite la lettre de réponse. Mêmes blocs, mêmes couleurs, simple miroir. La ligne de requête répond à la ligne de statut, les headers se répondent, le body se répond.

Deux lettres côte à côte. À gauche, la requête : ligne de requête (GET /produits HTTP/1.1), headers (Host, Accept, Cookie), ligne vide, body. À droite, la réponse : ligne de statut (HTTP/1.1 200 OK), headers (Content-Type, Set-Cookie), ligne vide, body HTML. Une flèche part de la requête vers la réponse, une autre revient. La requête (demande) Ligne de requête GET /produits HTTP/1.1 Headers Host : www.boutique.fr Accept · Cookie ligne vide (le pli) Body (vide pour un GET) La réponse (retour) Ligne de statut (le tampon) HTTP/1.1 200 OK Headers Content-Type : text/html Set-Cookie ligne vide (le pli) Body <!DOCTYPE html> … le contenu de la page demande réponse
Requête et réponse : deux lettres en miroir. Le tampon (la ligne de statut) est la première chose qu'on lit au retour.
Prédis avant de lire

Tu tapes l'URL /admin sans être connecté. Le serveur va-t-il répondre 401, 403 ou 404 ?

Voir la réponse

Les trois se défendent, et c'est précisément pourquoi il faut les connaître. Si tu n'es pas identifié, la réponse logique est 401 : « dis-moi qui tu es d'abord ». Si tu es identifié mais sans les droits admin, c'est 403 : « je sais qui tu es, et c'est non ». Et certains serveurs renvoient volontairement 404 pour cacher l'existence de la page /admin aux curieux : un attaquant qui voit un 403 sait qu'il y a quelque chose à forcer, alors qu'un 404 lui fait croire que rien n'existe. Trois choix, trois logiques. Savoir les distinguer, c'est savoir lire l'intention derrière le tampon.

À toi : lis les tampons comme un facteur

Un terminal simulé. Tu vas envoyer des requêtes avec curl et l'option -i (qui affiche aussi les headers de réponse). À chaque commande, lis d'abord la ligne de statut : c'est le tampon. Tu verras défiler un 200, un 301, un 403 et un 404. Apprends à les reconnaître au premier coup d'œil.

🖥️ Terminal simulé · lire les réponses HTTP
$

At last, we talk

In lesson 4, the secure channel opened. DNS gave the address, TLS laid down the encrypted handshake, and now the pipe is ready. But an open pipe says nothing by itself. You have to send something through it.

That something is a letter. Your browser writes a letter, slips it into the channel, and the server replies with another letter. That's all HTTP is: an exchange of letters. A request letter (the request), a reply letter (the response).

And like any letter, it has a structure: an address, an envelope covered in annotations, and some content. Learn to read this letter and the web holds no more secrets. You'll know why a site answers "404", what "301" means, and where to look when things break. Let's start with the request letter.

The request letter, line by line

Here is a real HTTP request, exactly as it travels down the channel. Raw, no makeup. Read it once, then we'll take it apart:

GET /produits/chaussures?taille=42 HTTP/1.1
Host: www.boutique.fr
User-Agent: Mozilla/5.0 ...
Accept: text/html
Cookie: session=abc123

The first line is the most important: it's the request line. It says three things, in order.

  • GET — the method. Here, "I want to read". More on that in a second.
  • /produits/chaussures?taille=42 — the path and the query string. Remember lesson 2: this piece comes straight from the URL. The browser split the URL and dropped its "path" part right here.
  • HTTP/1.1 — the version of the protocol used for this letter.

The following lines are the headers: the annotations on the envelope. Each one tells the server about the context of the request. There are dozens, but here are the few that truly matter:

  • Host — the only mandatory header in HTTP/1.1. Why? Because one server, at one IP address, often hosts hundreds of different sites. The channel connects you to the machine, but the machine needs to know which site you're after. Without Host, it doesn't know which door to open.
  • User-Agent — your business card. Which browser, which system. The server can use it to tailor its reply (or for statistics).
  • Accept — what you can receive. Here text/html: "send me HTML". An API would rather say Accept: application/json.
  • Cookie — a small token the browser sends back on every visit. Here session=abc123. Keep this word in mind: it's the seed of lesson 6, the one that explains how the site remembers you.

On the sending side: when you send data (a form, a file), one more header appears: Content-Type. It announces the format of the content you attach, for example application/json or application/x-www-form-urlencoded. It lets the server know how to read what you slip into the envelope.

The methods: four verbs for four intentions

The method is the verb at the head of the letter. It announces your intention. Four are enough to cover the essentials:

  • GET — read. You request a resource without changing anything. Open a page, load an image, view a product sheet.
  • POST — create or send. You transmit data that produces an effect: post a comment, confirm a cart, create an account.
  • PUT — replace. You overwrite an existing resource with a complete new version.
  • DELETE — delete. You request the removal of a resource.

A word on idempotence, which sounds clever but fits in two sentences. Replaying a GET, PUT or DELETE leaves the server in the same state: reading twice changes nothing, deleting twice gives the same "it's deleted". Replaying a POST, however, creates a duplicate: confirm your cart twice and you get two orders. That's why the browser warns you before "resubmitting the form".

Reminder: you met these verbs in the PHP course, with forms. A <form method="get"> sends a GET request (the fields go into the URL query string), a <form method="post"> sends a POST (the fields go into the body). It's the exact same mechanism, seen here from the network.

The response letter, and its stamp

The server read your letter. It replies with its own. Same logic, mirror structure:

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 1834
Set-Cookie: session=abc123

<!DOCTYPE html>
<html> ... </html>

Let's take it apart:

  • The status line (HTTP/1.1 200 OK) — it's the stamp on the letter. The code 200 and its label OK say at a glance how it went. It's the first thing you read.
  • The headersContent-Type announces the format of the returned content (HTML in UTF-8), Content-Length gives its size in bytes, and Set-Cookie asks the browser to remember a cookie. That lesson-6 seed again: notice that the server sets the cookie with Set-Cookie, and the browser will then send it back with Cookie.
  • The blank line — it separates the headers from the content. It's the fold of the envelope. Everything after it is the body.
  • The body — the content. Here, the HTML of the page. For an API, it would be JSON. For an image, raw bytes.

Status codes: four families, not a list to memorise

There are about sixty status codes. Nobody knows them all by heart, and there's no need. The secret is to remember the families, that is, the first digit. One mnemonic does the job:

"2xx it works, 3xx it's elsewhere, 4xx it's you, 5xx it's them."

"You" is the client (your browser). "Them" is the server. With this reflex, you already know which side to look at before even reading the detail. Here are the eight codes that cover 95% of your dev life:

  • 200 OK — all went well, here's what you asked for.
  • 301 vs 302 — two redirects. The 301 is permanent ("this page moved for good, memorise the new address"), the 302 is temporary ("look elsewhere for now, but come back here later"). The nuance matters for SEO, more on that in the quiz.
  • 304 Not Modified — "nothing changed since your last visit, keep your copy". Seed of lesson 7 on caching.
  • 400 Bad Request — your letter is malformed, the server doesn't understand it.
  • 401 vs 403 — two refusals, but not for the same reason. 401 Unauthorized = "I don't know who you are, identify yourself". 403 Forbidden = "I know who you are, and you're not allowed". Not identified versus identified-but-forbidden.
  • 404 Not Found — the requested resource doesn't exist. The great classic.
  • 500 Internal Server Error — the server crashed while handling your request. The bug is on their side.
  • 503 Service Unavailable — the server is temporarily overloaded or under maintenance. Come back later.

The first digit already tells you WHERE to look for the bug. A 4xx? Look at what your client sends: wrong URL, invalid data, missing rights. A 5xx? No point digging through your request, the problem is on the server side: logs, database, crashed code. Before diving into details, read the first digit. It saves you half the useless searching.

The two letters, side by side

Keep this picture in mind: on the left the request letter, on the right the response letter. Same blocks, same colours, a simple mirror. The request line answers the status line, the headers answer each other, the body answers the body.

Two letters side by side. On the left, the request: request line (GET /produits HTTP/1.1), headers (Host, Accept, Cookie), blank line, body. On the right, the response: status line (HTTP/1.1 200 OK), headers (Content-Type, Set-Cookie), blank line, HTML body. An arrow goes from the request to the response, another comes back. The request (ask) Request line GET /produits HTTP/1.1 Headers Host: www.boutique.fr Accept · Cookie blank line (the fold) Body (empty for a GET) The response (reply) Status line (the stamp) HTTP/1.1 200 OK Headers Content-Type: text/html Set-Cookie blank line (the fold) Body <!DOCTYPE html> … the page content ask reply
Request and response: two mirrored letters. The stamp (the status line) is the first thing you read on the way back.
Predict before reading on

You type the URL /admin without being logged in. Will the server reply 401, 403 or 404?

Show the answer

All three can be justified, and that's precisely why you need to know them. If you're not identified, the logical reply is 401: "tell me who you are first". If you're identified but without admin rights, it's 403: "I know who you are, and the answer is no". And some servers deliberately return 404 to hide the existence of the /admin page from prying eyes: an attacker who sees a 403 knows there's something to break into, whereas a 404 makes them believe nothing exists. Three choices, three logics. Knowing how to tell them apart is knowing how to read the intent behind the stamp.

Your turn: read the stamps like a postman

A simulated terminal. You'll send requests with curl and the -i flag (which also shows the response headers). On each command, read the status line first: that's the stamp. You'll see a 200, a 301, a 403 and a 404 go by. Learn to recognise them at a glance.

🖥️ Simulated terminal · reading HTTP responses
$

🎯 Pratique

S'entraîner (clique pour ouvrir) :

💬 Ré-explique sans regarder
Ré-explique sans regarder

Explique à un collègue les quatre familles de status codes (2xx, 3xx, 4xx, 5xx) avec la phrase mnémo, et donne un exemple de code dans chacune.

Une bonne explication dit : 2xx ça marche (ex. 200), 3xx c'est ailleurs (ex. 301, redirection définitive), 4xx c'est toi, le client (ex. 404 page absente, 403 interdit), 5xx c'est lui, le serveur (ex. 500 plantage). Le réflexe clé : le premier chiffre te dit déjà de quel côté chercher le bug, client ou serveur.
🧠 Rappel libre
Rappel libre

Sans remonter : quelle est la différence exacte entre 401 et 403 ?

401 Unauthorized = « je ne sais pas qui tu es, identifie-toi » : tu n'es pas authentifié. 403 Forbidden = « je sais qui tu es, mais tu n'as pas le droit » : tu es authentifié mais sans la permission. Pas identifié contre identifié-mais-interdit. (Certains serveurs renvoient un 404 à la place d'un 403 pour cacher l'existence de la ressource.)
⚖️ Juge le code de l'IA
Accepter ou rejeter le code de l'IA

Tu demandes à l'IA un bouton « Supprimer » pour effacer un article. Elle répond : « Fait ! Le bouton est un lien <a href="/delete?id=42">Supprimer</a>, ça appelle l'URL et l'article est supprimé. » Tu acceptes, ou tu rejettes ?

À rejeter : un lien <a> déclenche une requête GET, et un GET doit être sans effet (lire, pas modifier). Or ici il supprime. C'est un vrai trou : un crawler, un préchargeur de navigateur ou un simple bouton « précédent » peut rejouer le lien et effacer des données sans que personne n'ait cliqué. Le bon choix : une suppression passe par un POST (ou DELETE) déclenché par un vrai formulaire ou du JavaScript, jamais par un GET dans un lien. Règle : GET lit, il ne change jamais l'état.
Tu envoies un formulaire de connexion, mais le mot de passe est vide et le serveur juge la requête mal formée. Quel code renvoie-t-il ?
Une page charge bien, mais une image dedans affiche une erreur. Sa réponse commence par 5. Où chercher le bug ?
Tu accèdes à /factures/2024.pdf, connecté avec ton compte, mais cette facture appartient à un autre client. Quel code est le plus juste ?
Tu déplaces définitivement /blog/vieil-article vers une nouvelle URL. Pour le SEO, faut-il un 301 ou un 302, et pourquoi ?
Next step

You can read the letter: the request, the response, and the stamp that says how it went. But the postman has an embarrassing secret: between two letters, he remembers NOTHING. Every request starts from scratch. So how does the site know you're logged in? Lesson 6: stateless, cookies and sessions, the web's memory trick.

Lesson 6: Stateless, cookies and sessions →
Besoin d'un développeur pour votre projet ?

Réponse sous 24h · Sans engagement