http

HTTP outils

Une référence pratique pour déboguer HTTP : sémantique des statuts et des redirections, directives Cache-Control, et l'outil à saisir quand en-têtes, URL ou cartes de partage se comportent mal.

9 outils

§01 GUIDE DU DOMAINE

Ce que vous déboguez réellement

Un échange HTTP se décompose en quatre choses séparables, et l’essentiel du temps de débogage perdu vient de leur confusion : l’URL (ce que vous avez demandé), les en-têtes de requête (qui vous prétendez être et ce que vous acceptez), la ligne de statut (le verdict) et les en-têtes de réponse (le contrat de mise en cache, de sécurité et de type de contenu). Le corps est la partie la moins intéressante — quand il est faux, les en-têtes ont déjà expliqué pourquoi.

Deuxièmement, presque rien de ce qu’un navigateur vous montre n’est la sortie brute de l’origine. Entre votre serveur et le panneau Network se glissent un CDN, peut-être un proxy, HTTP/2 ou /3 (qui mettent en minuscules les noms de champs et abandonnent la phrase de raison), un service worker et le cache disque. Une ligne 200 OK (from disk cache) est le souvenir d’une réponse, pas une réponse — quand un en-tête semble absent, demandez-vous donc d’abord de qui est la copie que vous lisez.

Troisièmement, HTTP est largement déclaratif : User-Agent, Referer, Accept-Language et chaque en-tête personnalisé X- sont des affirmations qu’un client a choisi d’envoyer, falsifiables en une ligne de code. Seul ce que l’origine émet — le code de statut et les en-têtes de réponse — vous appartient.

Les classes de statut d’un coup d’œil

ClasseSignificationCe que le client devrait faireCacheable par heuristique
1xxProvisoire (100, 101, 103)Continuer d’attendreNon
2xxSuccèsUtiliser le corps (204 n’en a pas)200, 203, 204, 206
3xxRedirection / revalidationSuivre Location ; réutiliser le cache sur 304300, 301, 308
4xxErroné tel qu’envoyéCorriger ; ne pas réessayer à l’aveugle404, 405, 410, 414
5xxLe serveur a échoué sur une requête valideRalentir ; honorer Retry-After501 seulement

Deux codes sont couramment mal gérés : 429 devrait porter Retry-After, et 304 Not Modified est un succès — le journaliser comme une erreur masque un cache qui fonctionne.

La matrice des redirections que l’on se trompe

CodePermanenceMéthode et corps préservésÀ utiliser pour
301PermanentNon — peut devenir GETURL renommée, consolidation d’hôtes
302TemporaireNon — même risque de réécritureDéfaut historique ; à éviter pour POST
303TemporaireNon — force GETPOST puis redirection vers un résultat
307TemporaireOuiDéplacement temporaire d’un point d’API
308PermanentOuiDéplacement permanent d’un point POST

Les navigateurs mettent aussi les 301 durement en cache, parfois pour la durée de vie du profil : un 301 erroné est donc coûteux à défaire — vérifiez d’abord en préproduction.

Cache-Control, directive par directive

DirectiveGouverneRemarque
max-age=NFraîcheur en secondes, tout cache0 force la revalidation
s-maxage=NFraîcheur pour les caches partagés seulementSupplante max-age au CDN
no-cacheStockage oui ; revalider avant réutilisationCe n’est pas no-store
no-storeInterdit de stocker la réponseHTML authentifié
privateLe navigateur peut stocker, les caches partagés nonRéponses personnalisées
must-revalidatePas de service périmé en cas d’erreurÀ associer à max-age
immutableNe jamais revalider tant que fraisRessources au nom haché
stale-while-revalidate=NServir périmé, rafraîchir en arrière-planLisse les défauts de cache CDN

Vary appartient aussi à cette liste : si une réponse diffère selon Accept-Language ou un en-tête personnalisé et que vous ne le déclarez jamais, un cache partagé remet la mauvaise variante au visiteur suivant.

Quel outil pour quelle question

Quand vous avez une URL et voulez la réponse propre de l’origine, utilisez En-têtes HTTP : la requête part de api.sitekits.dev, donc aucune extension, aucun cache ni service worker n’est sur le chemin, et vous obtenez le statut final, l’URL finale, le nombre de sauts et chaque en-tête de réponse. Il ne lit que les en-têtes, jamais le corps, et sa protection SSRF rejette localhost et les plages privées.

Quand il vous faut envoyer quelque chose de précis — un PATCH avec un corps JSON, un en-tête Authorization: Bearer, un OPTIONS nu pour lire une prévérification — utilisez le Testeur REST API. Les requêtes partent de votre navigateur droit vers la cible, si bien que sa politique CORS s’applique exactement comme pour votre propre code frontal — idéal quand le bogue est le CORS. Si le jeton est le suspect, collez-le dans le Décodeur JWT pour lire exp et les revendications ; décoder n’est pas vérifier.

Quand l’unité fautive est un chargement de page entier plutôt qu’une requête, exportez un HAR dans la Visionneuse HAR ; le guide de terrain HAR couvre les temps. Les mystères de chaîne de requête tombent devant le Parseur d’URL, qui liste les paramètres décodés depuis l’encodage pourcent via l’analyseur WHATWG du navigateur, auquel s’ajoute URL Encode quand une valeur a été échappée une fois de trop. Le Parseur UserAgent réduit une chaîne UA au navigateur, au système, à la classe d’appareil et à une heuristique de robot ; les codes inconnus vont aux Codes HTTP ; un fichier qui se télécharge au lieu de s’afficher est généralement une question de Content-Type pour le Vérificateur MIME. Quand la réponse est saine mais que la carte de partage est fausse, collez le HTML de la page dans l’Aperçu OG — l’analyse est locale, cela fonctionne donc sur des builds de préproduction et derrière une authentification.

Pièges

Strict-Transport-Security sur une réponse HTTP ne fait rien

Les navigateurs ignorent HSTS livré en HTTP simple, et les cookies Secure y sont également abandonnés. Servez la redirection de mise à niveau sur le port 80 et les en-têtes de sécurité sur la réponse HTTPS — et vérifiez les deux sauts, pas seulement le dernier.

Les en-têtes de sécurité sont par réponse, pas par site

Un Content-Security-Policy durci sur votre HTML ne dit rien du JSON de votre API, des pages d’erreur de votre CDN, ni d’un bucket d’envois ailleurs. Le Générateur CSP écrit l’en-tête ; c’est votre configuration de déploiement qui décide quelles réponses le portent.

Les chaînes de redirections coûtent des allers-retours

http://example.comhttps://example.comhttps://www.example.com//home/ coûte trois allers-retours supplémentaires avant le moindre HTML, et chaque saut peut abandonner une méthode, un cookie ou une chaîne de requête. Réduisez-la à un seul saut à la périphérie.

Un 200 avec une erreur dans le corps met en échec la supervision par statut

Répondre 200 alors que la charge utile dit {"error": ...} masque les défaillances aux alertes indexées sur la classe de statut et gonfle la disponibilité mesurée. Si vous êtes responsable du SLO, contrôlez aussi la charge utile — voyez les outils rassemblés pour le travail SRE.

+ et %20 ne sont pas interchangeables

Dans une chaîne de requête encodée en application/x-www-form-urlencoded, + se décode en espace ; dans un segment de chemin, c’est un plus littéral. Le double-encodage est le bogue frère : %20 devient %2520 et la panne ressemble à du routage, pas à de l’échappement.

FAQ
Pourquoi mon POST s'est-il transformé en GET après une redirection ?
Parce que 301 et 302 autorisent les clients à réécrire la méthode en GET et à abandonner le corps, et les navigateurs font exactement cela. Utilisez 307 pour un déplacement temporaire et 308 pour un déplacement permanent lorsque la méthode et le corps doivent survivre au saut. Un formulaire ou un webhook qui perd silencieusement sa charge utile tombe généralement sur une redirection http vers https ou de barre oblique finale configurée en 301.
Pourquoi les en-têtes de réponse dans DevTools diffèrent-ils de ce que dit la configuration de mon serveur ?
Ce que DevTools montre est la réponse après tous les sauts. Un CDN, un proxy inverse ou un service worker peut ajouter, réécrire ou retirer des en-têtes, HTTP/2 et /3 mettent en minuscules chaque nom de champ et abandonnent la phrase de raison, et une ligne marquée 200 (from disk cache) n'est pas une réponse fraîche du tout. Charger l'URL côté serveur élimine ces variables et montre ce que l'origine a émis pour l'URL finale de la chaîne.
Cache-Control no-cache empêche-t-il les navigateurs de stocker ma page ?
Non. no-cache autorise le stockage mais exige une revalidation auprès de l'origine, normalement via ETag et If-None-Match, avant qu'une copie stockée soit réutilisée. no-store est la directive qui interdit d'écrire la réponse sur disque. Du HTML authentifié veut généralement private, no-store, tandis que des ressources statiques au nom haché veulent un long max-age plus immutable.
Pourquoi mon API fonctionne-t-elle avec curl mais échoue-t-elle dans le navigateur avec une erreur CORS ?
Le CORS est appliqué par le navigateur, pas par le serveur, et curl l'ignore entièrement. Pour tout ce qui dépasse une requête simple, le navigateur envoie d'abord une prévérification OPTIONS, et il refuse d'exposer la réponse à moins que l'origine ne renvoie un Access-Control-Allow-Origin correspondant, plus Access-Control-Allow-Credentials quand des cookies sont en jeu. Le serveur répond souvent 200 parfaitement bien ; vous ne pouvez simplement pas le lire. Inspectez d'abord la réponse à OPTIONS.
Pourquoi mon en-tête Strict-Transport-Security est-il ignoré ?
Parce que les navigateurs n'honorent HSTS que lorsqu'il arrive en HTTPS. Une politique servie sur une réponse en HTTP simple est purement écartée — de même que tout cookie Secure défini là — la réponse sur le port 80 devrait donc porter la redirection de mise à niveau et rien d'autre, les en-têtes de sécurité étant attachés à la réponse HTTPS. Vérifiez chaque saut plutôt que le 200 final : un en-tête présent au bout d'une chaîne de redirections ne dit rien de ce que le premier saut a envoyé. Rappelez-vous que includeSubDomains et preload engagent chaque sous-domaine en HTTPS pour le max-age que vous avez publié, et que le retrait de la liste de preload prend des mois.