Code 302 Found : à quoi sert une redirection temporaire
Un code 302 indique que la ressource demandée est servie provisoirement à une autre adresse, transmise dans l'en-tête Location, mais que l'URL d'origine reste la bonne. Le client suit la redirection sans enregistrer le changement, contrairement au 301 qui annonce un déménagement définitif.
Ce que contient réellement une réponse 302
Le serveur répond 302 pour dire une chose simple : la page existe, elle est juste servie ailleurs en ce moment. L'adresse de remplacement voyage dans l'en-tête Location, et il n'en faut pas plus. Une réponse typique tient en trois lignes.
Le nom officiel est Found depuis la RFC 7231, remplacée par la RFC 9110 (section 15.4.3) en juin 2022. L'ancien libellé Moved Temporarily, hérité de HTTP/1.0, traîne encore dans des logs Apache, des vieux proxys et certains outils d'audit. C'est le même code, pas un statut différent.
Point souvent ignoré : un 302 n'est pas stockable en cache par défaut. La RFC 9110 énumère les statuts mis en cache sans directive explicite (200, 203, 204, 206, 300, 301, 308, 404, 405, 410, 414 et 501) et le 302 n'y figure pas. Si vous voulez qu'un CDN ou un proxy retienne la redirection, il faut l'autoriser avec un Cache-Control: max-age. À l'inverse, un 301 mal posé se grave dans le cache du navigateur et vous poursuit pendant des mois.
La valeur de Location peut être absolue ou relative. Les deux formes sont valides depuis la RFC 7231, mais une URL relative derrière un reverse proxy mal configuré donne vite une redirection vers un hôte interne.
- HTTP/1.1 302 Found
- Location: /connexion?next=/facturation
- Content-Length: 0
302, 301, 303, 307, 308 : lequel poser
Les cinq codes de redirection se distinguent sur deux axes seulement : la permanence annoncée, et le fait de conserver ou non la méthode HTTP d'origine. Tout le reste en découle.
En pratique, la règle tient en une phrase : si l'ancienne URL doit disparaître, c'est 301 ou 308 ; si elle reprendra du service, c'est 302 ou 307. Un site qui bascule vers une page de campagne pendant trois semaines relève du 302. Une migration de domaine, jamais.
| Code | Nom | Durée annoncée | Méthode conservée | Cache par défaut |
|---|---|---|---|---|
| 301 | Moved Permanently | Permanente | Non (POST devient GET) | Oui |
| 302 | Found | Temporaire | Non (POST devient GET) | Non |
| 303 | See Other | Temporaire | Non, force le GET | Non |
| 307 | Temporary Redirect | Temporaire | Oui | Non |
| 308 | Permanent Redirect | Permanente | Oui | Oui |
L’impact sur le référencement
Google classe 301 et 308 comme redirections permanentes, 302, 303 et 307 comme temporaires. La conséquence porte sur la canonicalisation : face à un 302, le moteur a tendance à conserver l'URL de départ comme URL canonique, puisque vous lui annoncez que la situation va se rétablir. Face à un 301, il transfère la canonicalisation vers la cible.
Cela explique le symptôme classique : une migration entière posée en 302, et six semaines plus tard les anciennes URL sont toujours affichées dans les résultats. Rien n'est cassé au sens technique, le moteur applique simplement ce que vous avez déclaré. Google précise aussi qu'une redirection temporaire maintenue très longtemps finit par être traitée comme permanente, mais ce basculement n'a pas de délai documenté : ne comptez pas dessus.
Deux cas où le 302 est le bon choix : un test A/B qui envoie une partie du trafic vers une variante, et une redirection saisonnière (une page de soldes qui reprendra son contenu normal). Deux cas où il ne l'est pas : la bascule HTTP vers HTTPS, et l'unification www / domaine nu. Ces deux-là appellent un 301, complété par un en-tête HSTS pour la partie HTTPS.
Pour une maintenance réelle, ni 301 ni 302 : un 503 avec un en-tête Retry-After indique au crawler de repasser plus tard sans toucher à l'index.
Le piège du POST transformé en GET
Voici la panne qui coûte le plus de temps à diagnostiquer. Un formulaire envoie POST /panier/valider, le serveur répond 302, et le navigateur repart en GET vers la cible, corps de requête perdu. La commande n'est jamais enregistrée, et les logs applicatifs ne montrent qu'un GET parfaitement normal.
Ce comportement n'est pas un bug de navigateur, c'est un usage devenu si répandu que la spécification l'a entériné. La RFC 9110 note explicitement que de nombreux agents utilisateurs changent la méthode en GET sur un 302. Les codes 303 et 307 ont justement été créés pour lever l'ambiguïté : 303 force le GET de façon assumée, 307 garantit que la méthode et le corps sont rejoués à l'identique.
Si vous avez besoin qu'un POST reste un POST après redirection (une API interne, un webhook réacheminé), utilisez 307. Si au contraire vous voulez le motif Post/Redirect/Get, qui évite la double soumission quand l'utilisateur rafraîchit la page de confirmation, alors 302 ou 303 font exactement le travail attendu.
Émettre et diagnostiquer un 302
La plupart des frameworks envoient un 302 par défaut, ce qui surprend quand on croyait poser une redirection définitive. En PHP, header('Location: /connexion'); produit un 302. En Express, res.redirect('/connexion') aussi. Django renvoie 302 avec redirect(), et 301 seulement si vous passez permanent=True.
Côté serveur web, nginx utilise return 302 https://exemple.fr/nouvelle-page; ou le drapeau redirect d'une directive rewrite, là où permanent donne un 301. Apache accepte Redirect 302 /ancien /nouveau ou RewriteRule ^ancien$ /nouveau [R=302,L].
Pour vérifier, curl -sI https://exemple.fr affiche le statut et le Location sans télécharger le corps. Ajoutez -L pour suivre la chaîne complète et repérer les sauts inutiles. Un enchaînement 302 vers 301 vers 200 fonctionne pour l'utilisateur mais gaspille deux allers-retours réseau sur chaque visite.
La boucle de redirection est l'autre défaillance fréquente. curl s'arrête après 50 sauts et affiche « Maximum (50) redirects followed » ; les navigateurs coupent plus tôt, autour de vingt sauts, avec ERR_TOO_MANY_REDIRECTS sur Chrome. La cause la plus courante derrière un CDN : le proxy termine le TLS et transmet la requête en HTTP interne sans en-tête X-Forwarded-Proto exploitable, donc l'application croit être en clair et redirige vers HTTPS indéfiniment. Le test qui tranche : appelez l'origine directement, en contournant le CDN, et regardez si le 302 est toujours là.
- curl -sI https://exemple.fr : statut et en-tête Location, sans le corps
- curl -sIL https://exemple.fr : la chaîne entière, saut par saut
- curl -sI -H 'X-Forwarded-Proto: https' http://origine.interne : isole une boucle liée au proxy
- Onglet Réseau du navigateur, colonne Statut : les 302 y apparaissent en gris au-dessus de la réponse finale
Testez vos connaissances
Quel en-tête indique la destination d'une réponse 302 ?
Score : 0 sur 3
Questions fréquentes
Un 302 fait-il perdre des positions dans Google ?
Pas par lui-même. Le problème vient du signal envoyé : en annonçant une situation temporaire, vous demandez au moteur de garder l'ancienne URL comme canonique. Si l'ancienne page n'a plus de contenu propre, elle reste indexée avec un contenu qui n'est plus le sien. Pour un changement définitif, posez un 301.
Combien de temps peut-on laisser une redirection 302 en place ?
Le temps que dure réellement la situation temporaire. Aucun délai n'est fixé par la spécification ni documenté par les moteurs. Si vous ne savez plus quand l'ancienne URL reprendra son contenu, c'est le signe qu'il fallait un 301.
Quelle différence pratique entre 302 et 307 ?
Sur un GET, aucune : les deux redirigent vers Location. La différence apparaît sur POST, PUT ou DELETE. Le 307 rejoue la méthode et le corps à l'identique, le 302 laisse les navigateurs les convertir en GET. Pour rediriger un appel d'API ou une soumission de formulaire, prenez 307.
Comment savoir si une URL renvoie un 302 ?
curl -sI suivi de l'URL affiche la première ligne de réponse et l'en-tête Location. Dans un navigateur, ouvrez l'onglet Réseau, décochez le filtre qui masque les requêtes intermédiaires et lisez la colonne Statut. Attention : une redirection JavaScript ou une balise meta refresh ne produit aucun code 3xx, elles n'apparaissent pas de la même façon.
Faut-il mettre en cache un 302 ?
Par défaut non, et c'est voulu. Si la redirection change souvent (test A/B, routage géographique), laissez-la non stockable. Si elle est stable sur plusieurs heures et que le volume justifie de soulager l'origine, ajoutez Cache-Control: max-age=3600, en gardant à l'esprit qu'un client ayant mis la réponse en cache ne repassera pas par vous avant expiration.