Code 302 : à quoi sert une redirection temporaire
Le code HTTP 302 Found indique que la ressource demandée est provisoirement accessible à une autre adresse, indiquée dans l'en-tête Location, sans que l'URL d'origine perde sa validité. C'est le code à utiliser pour une bascule temporaire, jamais pour une migration définitive où 301 ou 308 s'imposent.
Ce qu’un serveur envoie réellement avec un 302
Un 302 n'est pas une page, c'est une consigne. Le serveur répond avec la ligne de statut 302 et un en-tête Location qui donne l'adresse à suivre. Le client refait alors sa requête sur cette adresse. Vous pouvez le voir en une commande :
curl -sI https://exemple.fr/promo HTTP/2 302 location: https://exemple.fr/promo-ete cache-control: no-store
Notez l'absence du mot Found à côté du 302 : HTTP/2 a supprimé la phrase de raison, seul le nombre circule sur le fil. Le libellé Found vient de la RFC 2616 ; en HTTP/1.0 (RFC 1945) le même code s'appelait Moved Temporarily, et c'est cette formulation qui décrit le mieux son rôle. La définition en vigueur est celle de la RFC 9110, section 15.4.3.
Location accepte une référence relative autant qu'une URL absolue, ce que la RFC 7231 avait déjà entériné. Un 302 sans Location reste syntaxiquement valide mais laisse le client sans destination : le navigateur affiche alors le corps de la réponse, souvent vide, et l'utilisateur voit une page blanche. Si vous générez vos redirections en code, vérifiez toujours que l'en-tête part bien avec le statut.
302, 301, 303, 307, 308 : lequel choisir
Les cinq codes de redirection utiles se distinguent sur deux axes : la permanence annoncée, et le fait de conserver ou non la méthode HTTP d'origine.
Le choix a des conséquences durables. Un 301 est mis en cache agressivement par les navigateurs : si vous vous trompez de cible, les visiteurs qui ont déjà reçu la redirection continueront d'atterrir au mauvais endroit tant qu'ils ne vident pas leur cache. Le 302 n'a pas ce défaut, ce qui en fait le bon candidat pendant une phase de test.
| Code | Sens | Méthode HTTP conservée | Mise en cache par défaut |
|---|---|---|---|
| 301 Moved Permanently | Déplacement définitif | Non en pratique, POST devient GET | Oui |
| 302 Found | Déplacement temporaire | Non en pratique, POST devient GET | Non, sauf en-tête explicite |
| 303 See Other | Voir ailleurs après traitement | Non, GET imposé par la spécification | Non |
| 307 Temporary Redirect | Temporaire, strict | Oui | Non |
| 308 Permanent Redirect | Définitif, strict | Oui | Oui |
Le piège du POST transformé en GET
Voici le comportement qui surprend le plus. Un client envoie POST /panier, le serveur répond 302 vers /panier/confirmation, et le navigateur repart en GET, sans le corps de la requête. Ce n'était pas prévu par la spécification d'origine, mais tous les navigateurs le faisaient, et la RFC 7231 a fini par documenter cet écart plutôt que de le combattre.
Dans un formulaire web, c'est même souhaitable : le motif POST/Redirect/GET évite le doublon de commande quand l'utilisateur rafraîchit la page. Le problème apparaît ailleurs. Un webhook de paiement, un appel d'API, un client curl qui envoie du JSON en POST : si votre couche de redirection répond 302, la charge utile disparaît et le service distant reçoit un GET vide. Le symptôme classique côté logs est une requête à 0 octet là où vous attendiez plusieurs kilooctets.
La correction tient en un chiffre : remplacez 302 par 307. Le 307, défini en RFC 9110 section 15.4.8, interdit explicitement au client de changer de méthode. Si à l'inverse vous voulez forcer le passage en GET après traitement d'un formulaire, 303 See Other est le code prévu pour cela.
302 et référencement : ce que fait Google
Google documente une distinction nette entre redirections temporaires et permanentes. Face à un 302, le moteur conserve l'URL de départ dans son index et y affiche le contenu de la cible. Face à un 301 ou un 308, il finit par remplacer l'ancienne URL par la nouvelle dans les résultats.
D'où l'erreur la plus coûteuse en pratique : migrer un site entier en 302. Les anciennes adresses restent indexées, les nouvelles peinent à s'installer, et le rapport Couverture de la Search Console se remplit d'URL en doublon. Pour un changement de domaine ou une refonte d'arborescence, 301 ou 308 uniquement.
Google précise qu'une redirection temporaire maintenue très longtemps peut finir par être interprétée comme permanente. Aucune durée seuil n'est publiée, et il serait malhonnête d'en inventer une : traitez cette bascule comme un effet de bord non contrôlable, pas comme une stratégie.
Attention aussi aux chaînes. Chaque saut ajoute un aller-retour réseau, et Googlebot ne suit qu'un nombre limité de sauts par tentative d'exploration, dix selon la documentation Google, avant de signaler une erreur de redirection. Si votre configuration enchaîne http vers https, puis sans www vers www, puis ancienne URL vers nouvelle, vous consommez trois sauts pour rien. Écrivez la règle qui mène directement à la destination finale.
- Cas légitimes pour un 302 : page produit en rupture renvoyée vers sa catégorie, test A/B, opération saisonnière, maintenance planifiée, géolocalisation vers une version de langue
- Cas à proscrire : changement de domaine, passage en HTTPS, fusion de deux pages, suppression définitive d'une rubrique
Configurer et diagnostiquer un 302
La plupart des frameworks émettent un 302 par défaut, souvent sans que le développeur l'ait choisi. Savoir où se trouve le réglage évite les mauvaises surprises.
- Nginx : return 302 https://exemple.fr/nouvelle-page; dans le bloc location, ou rewrite ^/ancien$ /nouveau redirect; le mot-clé permanent donnerait un 301
- Apache avec mod_alias : Redirect 302 /ancien /nouveau, ou RewriteRule ^ancien$ /nouveau [R=302,L] avec mod_rewrite
- PHP : header('Location: /connexion'); envoie un 302 sans rien demander ; pour un autre statut, header('Location: /connexion', true, 307);
- Express : res.redirect('/connexion') vaut 302, res.redirect(308, '/connexion') pour une redirection permanente qui conserve la méthode
- Diagnostic : curl -sIL -o /dev/null -w '%{num_redirects} sauts vers %{url_effective}\n' https://exemple.fr affiche la longueur de la chaîne et la destination réelle
La boucle de redirection, panne la plus fréquente
Le scénario se répète sur presque toutes les infrastructures avec un reverse proxy. Le proxy termine le TLS et transmet la requête en HTTP clair à l'application. L'application, qui ne voit que du HTTP, croit bien faire et répond 302 vers la version HTTPS. Le proxy retermine, retransmet en clair, et la boucle est bouclée.
Le navigateur s'arrête au bout de vingt sauts, limite fixée par le standard Fetch, et affiche ERR_TOO_MANY_REDIRECTS sous Chrome. curl, lui, s'arrête à cinquante par défaut quand vous utilisez -L, et vous renvoie un message d'erreur explicite sur le nombre maximal atteint.
La cause est presque toujours la même : l'application ignore l'en-tête X-Forwarded-Proto que le proxy lui envoie. Sur un WordPress derrière un proxy, la correction consiste à définir $_SERVER['HTTPS'] à partir de cet en-tête avant le chargement de wp-config. Sur une application Laravel ou Symfony, il s'agit de déclarer le proxy comme fiable. Deuxième cause classique : une adresse de site enregistrée avec www en base de données pendant que le serveur redirige www vers le domaine nu.
Questions fréquentes
302 ou 301 pour une page en maintenance ?
302, sans hésiter. La page reviendra, son URL doit donc rester celle que Google connaît et garde en index. Un 301 dirait au moteur que l'adresse a disparu pour de bon, et vous devriez ensuite lutter pour la faire réindexer. Ajoutez Cache-Control: no-store pour que le navigateur ne conserve pas la redirection après la fin de l'intervention.
Un 302 fait-il perdre le référencement de la page ?
Non, la page de départ reste dans l'index et conserve ses signaux. Le problème n'est pas une perte, c'est un malentendu : si vous vouliez déplacer définitivement le contenu, Google continuera d'afficher l'ancienne URL dans ses résultats et la nouvelle restera dans l'ombre. Le mauvais code vous coûte du temps, pas de l'autorité.
Pourquoi mon formulaire perd ses données après une redirection ?
Parce que le navigateur transforme le POST en GET en suivant un 302, et abandonne le corps de la requête au passage. Vérifiez la réponse avec curl -sI sur l'URL du formulaire. Si vous devez impérativement conserver la méthode et la charge utile, par exemple pour un webhook, renvoyez 307 à la place.
Comment corriger une erreur ERR_TOO_MANY_REDIRECTS ?
Commencez par cartographier la boucle avec curl -sIL https://votresite.fr | grep -i '^location', qui liste chaque saut. Dans neuf cas sur dix, deux règles se contredisent : le serveur web force HTTPS pendant que l'application, derrière un proxy, croit être en HTTP clair et force HTTPS elle aussi. Faites confiance à X-Forwarded-Proto d'un seul côté.
Un navigateur met-il un 302 en cache ?
Pas par défaut. La RFC 9110 ne place pas 302 parmi les statuts stockables de façon heuristique, contrairement à 301 et 308. Un 302 n'est mis en cache que si vous l'accompagnez explicitement d'un Cache-Control ou d'un Expires. C'est ce qui rend le 302 réversible, là où un 301 mal ciblé reste collé aux navigateurs de vos visiteurs.
À lire aussi
codes statut http · cache · cdn · agent utilisateur
Testez vos connaissances
Quel en-tête accompagne obligatoirement un code 302 pour qu'il soit exploitable ?
Score : 0 sur 3