Comment déboguer les erreurs CORS dans le navigateur
Vous déclenchez une requête fetch, ouvrez la console et voyez quelque chose comme :
Access to fetch at ‘https://api.example.com’ from origin ‘http://localhost:3000’ has been blocked by CORS policy.
Avant de commencer à modifier les en-têtes du serveur au hasard, arrêtez-vous. La plupart du débogage CORS dans le navigateur se résume à lire ce que le navigateur vous dit déjà — si vous savez où chercher.
Points clés à retenir
- Les erreurs CORS sont appliquées par le navigateur, pas par le serveur. La requête atteint souvent le serveur ; le blocage se produit au niveau de la réponse.
- Le message de la console du navigateur est votre principal outil de diagnostic — il pointe souvent vers la règle ou l’en-tête défaillant, mais peut également refléter des problèmes réseau, TLS ou de politique sous-jacents.
- Les requêtes preflight OPTIONS échouent silencieusement si vous ne les cherchez pas. Vérifiez toujours l’onglet Network filtré par “All” pour les repérer.
- Toutes les erreurs qui ressemblent à du CORS ne sont pas réellement des problèmes CORS. Le contenu mixte, les échecs TLS, les redirections et les extensions de navigateur peuvent tous se faire passer pour des problèmes CORS.
Ce que signifient réellement les erreurs CORS
Les erreurs CORS (Cross-Origin Resource Sharing) se produisent lorsque votre navigateur bloque une requête cross-origin parce que la réponse du serveur n’incluait pas les bonnes permissions. Le mot clé est navigateur — la requête atteint souvent le serveur. Le blocage se produit au retour.
Une origine est définie par la combinaison du protocole, du domaine et du port. Ainsi, http://localhost:3000 et http://localhost:4000 sont des origines différentes, même sur la même machine.
Comment déboguer les erreurs CORS avec les DevTools
Ouvrez DevTools → onglet Network (F12 ou Cmd+Option+I). Reproduisez la requête défaillante. Ensuite :
- Trouvez la requête échouée — recherchez une entrée rouge ou filtrez par “Fetch/XHR”.
- Vérifiez l’onglet Console — le message d’erreur y est spécifique. Il vous indique quel en-tête est manquant ou incorrect.
- Cliquez sur la requête → onglet Headers — inspectez à la fois les en-têtes de requête (notamment
Origin) et les en-têtes de réponse (notammentAccess-Control-Allow-Origin).
L’erreur de console est votre principal outil de diagnostic. Les versions modernes de Chrome et Firefox donnent des messages précis comme :
- “No ‘Access-Control-Allow-Origin’ header is present” → le serveur n’a envoyé aucun en-tête CORS.
- “The value of ‘Access-Control-Allow-Origin’ must not be the wildcard ’*’ when credentials mode is ‘include’” → vous utilisez
credentials: 'include'mais le serveur a répondu avec*. - “Method PUT is not allowed by Access-Control-Allow-Methods” → le preflight a rejeté votre méthode HTTP.
Déboguer les requêtes preflight (OPTIONS)
Lorsque votre requête utilise une méthode non simple (PUT, DELETE, PATCH), des en-têtes personnalisés ou un type de contenu autre que les quelques-uns autorisés par la spécification, le navigateur envoie d’abord une requête preflight OPTIONS. Si celle-ci échoue, votre requête réelle n’est jamais envoyée.
Dans l’onglet Network, filtrez par “All” et recherchez une requête OPTIONS vers la même URL, apparaissant juste avant votre requête principale. Cliquez dessus et vérifiez :
- En-têtes de requête :
Access-Control-Request-MethodetAccess-Control-Request-Headers— ceux-ci indiquent au serveur ce dont la vraie requête a besoin. - En-têtes de réponse :
Access-Control-Allow-Methods,Access-Control-Allow-Headers,Access-Control-Allow-Origin— le serveur doit explicitement autoriser chacun d’eux.
Si la requête OPTIONS retourne un code de statut 4xx ou 5xx, il s’agit probablement d’une erreur de routage ou de configuration côté serveur, et non d’une mauvaise configuration des en-têtes CORS. Corrigez d’abord l’erreur sous-jacente.
Discover how at OpenReplay.com.
Est-ce vraiment une erreur CORS ?
Toutes les erreurs qui apparaissent comme CORS ne sont pas causées par CORS. Les faux positifs courants incluent :
- Contenu mixte — récupérer du
http://depuis une pagehttps://est bloqué par la politique de contenu mixte du navigateur, indépendamment des en-têtes CORS. - Erreurs TLS/certificat — un échec de handshake TLS peut ressembler à un échec CORS dans la console.
- Redirections vers une origine différente — si le serveur redirige votre requête vers une nouvelle origine, le navigateur bloque la requête. Les redirections cross-origin ne sont pas autorisées pour les requêtes CORS.
- Extensions de navigateur — les extensions de confidentialité ou de blocage de publicités peuvent annuler les requêtes avant même que CORS ne soit évalué.
- Restrictions de cookies tiers — si vous utilisez
credentials: 'include', les navigateurs modernes peuvent bloquer les cookies d’origines tierces même lorsque vos en-têtes CORS sont parfaitement corrects.
Pour isoler la vraie cause, essayez la requête dans une fenêtre privée/incognito avec les extensions désactivées.
Requêtes avec credentials : un piège courant
Si vous utilisez fetch(url, { credentials: 'include' }), le serveur ne peut pas répondre avec Access-Control-Allow-Origin: *. Il doit renvoyer l’origine exacte qui fait la requête. Le serveur doit également inclure Access-Control-Allow-Credentials: true dans sa réponse. Manquez l’un ou l’autre et le navigateur bloque la réponse.
Liste de vérification rapide pour le débogage CORS
| Vérification | Ce qu’il faut rechercher |
|---|---|
| Message d’erreur de la console | En-tête ou règle exacte qui a échoué |
| Requête OPTIONS présente ? | Preflight déclenché — vérifiez sa réponse |
La réponse a Access-Control-Allow-Origin ? | Doit correspondre à votre origine ou être * |
| Utilisation de credentials ? | * n’est pas autorisé ; origine exacte requise |
| 4xx/5xx sur la requête ? | Erreur serveur — pas un problème CORS |
| Contenu mixte ? | HTTP depuis une page HTTPS — toujours bloqué |
Conclusion
Le message d’erreur du navigateur, l’onglet Network et le panneau Headers vous donnent tout ce dont vous avez besoin pour diagnostiquer la plupart des problèmes CORS en moins de cinq minutes. Lisez l’erreur exacte, trouvez la requête OPTIONS si elle existe, comparez ce qui a été envoyé avec ce qui était attendu, et travaillez à partir de là. Résistez à l’envie d’ajouter aveuglément Access-Control-Allow-Origin: * à votre serveur — comprenez d’abord ce que le navigateur demande, et répondez précisément.
FAQ
Non. CORS est appliqué par le navigateur en fonction des en-têtes envoyés par le serveur. Le frontend ne peut pas contourner cela. Si vous ne contrôlez pas le serveur, vous pouvez router les requêtes via un proxy backend qui ajoute les en-têtes corrects, mais le code côté navigateur seul ne peut pas contourner cette restriction.
Postman n'est pas un navigateur et n'applique pas la politique de même origine. Il envoie les requêtes directement sans vérifier les en-têtes CORS sur la réponse. Les navigateurs appliquent CORS pour protéger les utilisateurs, donc une requête qui réussit dans Postman peut toujours être bloquée par le navigateur si le serveur omet les en-têtes de réponse requis.
Un preflight est déclenché lorsque la requête utilise une méthode autre que GET, HEAD ou POST, inclut des en-têtes personnalisés, ou définit un Content-Type autre que application/x-www-form-urlencoded, multipart/form-data ou text/plain. Le navigateur envoie d'abord une requête OPTIONS pour confirmer que le serveur autorise la requête réelle.
Si votre requête inclut des credentials tels que des cookies ou des en-têtes d'autorisation, le serveur ne peut pas utiliser la valeur wildcard. Il doit répondre avec l'origine exacte qui a fait la requête et également inclure l'en-tête Access-Control-Allow-Credentials défini sur true. Le wildcard n'est valide que pour les requêtes sans credentials.
Gain control over your UX
See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.