Guides

Comment corriger les erreurs CORS (et pourquoi elles surviennent)

Une erreur CORS signifie que votre page web a tenté de lire une réponse provenant d’une autre origine (un autre domaine, port ou protocole), et que ce serveur n’a pas envoyé d’en-têtes indiquant que c’est autorisé. Les navigateurs bloquent la réponse pour protéger les utilisateurs. Vous corrigez cela sur le serveur, en renvoyant un en-tête Access-Control-Allow-Origin pour l’origine de votre site et en traitant les requêtes preflight OPTIONS, ou vous l’évitez en envoyant la requête via votre propre back end sur la même origine.

C’est l’une des erreurs les plus déroutantes en développement web, car la requête atteint souvent le serveur sans problème. Ce guide explique ce qui se passe et comment corriger chaque variante.

Ce que signifie « origine »

Une origine est la combinaison du protocole, du domaine et du port :

URLOrigine
https://monapp.com/dashboardhttps://monapp.com
https://api.monapp.com/usershttps://api.monapp.com (sous-domaine différent, donc origine différente)
http://localhost:5173http://localhost:5173
http://localhost:3000http://localhost:3000 (port différent, donc origine différente)

Les navigateurs appliquent la politique de même origine : le JavaScript d’une page peut lire librement les réponses de sa propre origine, mais pas celles des autres. CORS (Cross-Origin Resource Sharing, partage des ressources entre origines) est le mécanisme qui permet à un serveur d’y consentir : « les réponses de ce serveur peuvent être lues par des pages venant de ces origines ».

Deux conséquences surprennent souvent :

  • La requête atteint souvent le serveur. CORS empêche généralement votre code de lire la réponse, pas le serveur de recevoir la requête. Un POST peut avoir été enregistré alors que vous avez vu une erreur.
  • Seuls les navigateurs l’appliquent. curl, Postman et le code côté serveur ignorent totalement CORS. C’est pourquoi « ça marche dans Postman » ne vous apprend rien sur CORS.

Étape 1 : lire l’erreur exacte

Ouvrez les outils de développement (clic droit → Inspecter), allez dans la Console, et lisez le message complet. La formulation de Chrome indique le problème :

Le message contientCe qui ne va pas
No 'Access-Control-Allow-Origin' header is presentLe serveur n’a pas envoyé l’en-tête du tout, ou la requête a échoué avant d’atteindre votre code CORS (par exemple un 404 ou un 500)
The 'Access-Control-Allow-Origin' header has a value '...' that is not equal to the supplied originLe serveur autorise une autre origine que la vôtre
Response to preflight request doesn't pass access control checkLa requête OPTIONS preflight a échoué
...must not be the wildcard '*' when the request's credentials mode is 'include'Vous envoyez des cookies, et le serveur a répondu avec *
Request header field authorization is not allowedLe serveur n’a pas listé cet en-tête dans Access-Control-Allow-Headers

Ouvrez ensuite l’onglet Réseau, repérez la requête en échec (et toute requête OPTIONS qui la précède), et regardez son code de statut et ses en-têtes de réponse.

Vérifiez d’abord le code de statut. Beaucoup d’« erreurs CORS » sont en réalité une erreur serveur déguisée. Si le serveur plante ou renvoie un 404, sa réponse d’erreur n’a souvent pas les en-têtes CORS, donc le navigateur signale une erreur CORS au lieu du vrai problème. Corrigez le 500 ou le 404, et l’erreur CORS peut disparaître.

Étape 2 : décider si vous devez appeler cette API depuis le navigateur

Avant d’ajouter des en-têtes, demandez-vous : le navigateur doit-il appeler directement cette API ?

  • Une API tierce qui nécessite une clé secrète (OpenAI, clé secrète Stripe, la plupart des services d’e-mail) ne doit jamais être appelée depuis le navigateur. La clé serait visible par chaque visiteur. Appelez-la depuis votre back end, et le problème CORS disparaît, car les requêtes serveur à serveur ne sont pas soumises à CORS. Voir comment garder vos clés d’API en sécurité.
  • Une API tierce que vous ne contrôlez pas et qui n’envoie pas d’en-têtes CORS ne peut pas être corrigée de votre côté. Appelez-la depuis votre back end.
  • Votre propre API peut être corrigée en la configurant correctement. Continuez ci-dessous.

Étape 3 : corriger côté serveur

Le serveur doit ajouter les bons en-têtes à ses réponses, y compris les réponses d’erreur.

Pour la requête réelle, envoyez :

  • Access-Control-Allow-Origin: https://monapp.com (l’origine exacte de votre front-end, sans barre oblique finale)
  • Vary: Origin, si la valeur dépend de l’origine demandeuse

Pour la requête preflight OPTIONS, répondez avec un statut de succès (200 ou 204) et :

  • Access-Control-Allow-Origin: https://monapp.com
  • Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE
  • Access-Control-Allow-Headers: Content-Type, Authorization (chaque en-tête personnalisé que vous envoyez)
  • Optionnellement Access-Control-Max-Age: 600, pour que le navigateur mette le preflight en cache un moment

La plupart des frameworks ont un paquet ou un réglage qui fait cela. Dans Express, le paquet cors ; dans FastAPI, CORSMiddleware ; dans ASP.NET Core, AddCors ; dans Spring, @CrossOrigin ou une configuration CORS. Une configuration Express typique :

import cors from "cors";

app.use(cors({
  origin: ["https://monapp.com", "http://localhost:5173"],
  credentials: true,
}));

Placez la gestion CORS avant vos routes et votre authentification, pour que les requêtes preflight (qui ne transportent aucune connexion) ne soient pas rejetées avec un 401.

Avec un créateur d’applications par IA, décrivez précisément la configuration :

Le front-end sur https://monapp.com appelle l’API sur https://api.monapp.com et obtient « Response to preflight request doesn't pass access control check ». Configure CORS sur l’API pour autoriser exactement https://monapp.com et l’origine de l’aperçu, autorise GET, POST, PATCH, DELETE avec les en-têtes Content-Type et Authorization, traite OPTIONS avant l’authentification, et inclus aussi les en-têtes CORS dans les réponses d’erreur.

Étape 4 : gérer les cookies et les identifiants

Si votre front-end envoie des cookies (par exemple une session de connexion) vers une autre origine, les deux côtés doivent être d’accord :

  • Le front-end définit credentials: "include" dans fetch, ou withCredentials: true dans axios.
  • Le serveur envoie Access-Control-Allow-Credentials: true.
  • Le Access-Control-Allow-Origin du serveur doit être l’origine exacte, et non *.

Les cookies inter-sites ont aussi besoin de SameSite=None; Secure sur le cookie, et certains navigateurs restreignent davantage les cookies tiers. C’est une raison de plus de préférer l’approche de l’étape 5.

Étape 5 : éviter CORS avec une configuration de même origine

Souvent, la solution la plus propre consiste à ne pas faire de requêtes inter-origines du tout. Servez l’API depuis la même origine que la page, par exemple à https://monapp.com/api/... :

  • En développement, la plupart des serveurs de développement peuvent faire office de proxy. Le paramètre server.proxy de Vite peut transmettre /api à votre back end sur un autre port, de sorte que le navigateur ne parle qu’à une seule origine.
  • En production, routez /api vers le back end via les réglages de réécriture ou de proxy de votre hébergeur, ou servez le front-end et l’API depuis un même serveur.

Le front-end appelle alors un chemin relatif comme fetch("/api/orders"). Il n’y a plus de requête inter-origine, plus de preflight entre origines, plus de problèmes de cookies. Cela évite aussi de coder en dur un domaine d’API qui diffère entre l’aperçu et la production.

Modifie le front-end pour appeler le back end avec des chemins relatifs /api au lieu d’une URL complète, et configure un proxy de développement pour que /api soit transmis au serveur d’API. Supprime ensuite les réglages CORS dont nous n’avons plus besoin.

Ce qu’il ne faut pas faire

  • mode: "no-cors" dans fetch. Cela ne contourne rien ; cela donne à votre code une réponse vide et illisible.
  • Les extensions de navigateur qui désactivent CORS. Elles ne modifient que votre navigateur. Chaque visiteur verra toujours l’erreur.
  • Les services publics de « proxy CORS » pour de vraies applications. Ils peuvent lire et modifier tout ce qui transite par eux, et ils tombent en panne.
  • Access-Control-Allow-Origin: * sur une API qui utilise des connexions. Cela ne fonctionne pas avec les identifiants de toute façon, et c’est le mauvais choix par défaut pour des données privées.
  • Renvoyer n’importe quel en-tête Origin reçu avec les identifiants autorisés. Cela permet à n’importe quel site web de faire des requêtes connectées au nom de vos utilisateurs. Utilisez une liste d’autorisation.

Causes fréquentes dans les applications créées par IA

SituationCorrection
Le front-end appelle une API tierce avec une clé secrèteDéplacer l’appel vers le back end
Fonctionne dans l’aperçu, échoue sur le domaine publiéAjouter les origines publiées et du domaine personnalisé à la liste d’autorisation, ou utiliser des chemins relatifs /api
Erreur seulement sur POST, PUT ou DELETEPreflight non traité ; ajouter la gestion d’OPTIONS et les en-têtes autorisés
L’erreur est apparue après l’ajout de la connexionLes identifiants exigent une origine exacte et Allow-Credentials
« Erreur CORS » mais l’onglet Réseau affiche 500Corriger d’abord l’erreur serveur
URL de l’API codée en dur sur localhostUtiliser des chemins relatifs ou un réglage par environnement

CORS dans Mythex

Quand un projet Mythex comporte un site web et un serveur d’API, les deux tournent comme services dans le même projet, et vous pouvez basculer entre eux dans l’aperçu. Demander à l’agent que le front-end appelle le back end via un chemin relatif /api, proxifié en développement, évite la plupart des problèmes CORS. Si vous avez vraiment besoin d’appels inter-origines, donnez à l’agent l’erreur exacte de la console et les origines concernées. Vérifiez le résultat sur l’application publiée aussi, car son adresse diffère de celle de l’aperçu. Voir Applications multi-services et Back ends d’API dans la documentation, ainsi que nos guides sur le débogage d’une application créée par IA et front-end ou back-end.

Liste de contrôle CORS

  • Lu le message d’erreur complet dans la console et le code de statut de la requête en échec
  • Écarté un 404 ou un 500 masqué
  • Les API à clé secrète sont appelées depuis le back end, pas le navigateur
  • Le serveur envoie Access-Control-Allow-Origin avec les origines exactes autorisées
  • La requête preflight OPTIONS reçoit les méthodes et en-têtes autorisés, avant l’authentification
  • Les en-têtes CORS sont présents aussi dans les réponses d’erreur
  • Identifiants : origine exacte, Allow-Credentials: true, réglages de cookies corrects
  • Origines de l’aperçu, du domaine publié et du domaine personnalisé couvertes, ou chemins relatifs /api utilisés
  • Aucun raccourci no-cors, proxy public ou origine réfléchie sans contrôle

Questions

Que signifie une erreur CORS ?

Votre page, chargée depuis une origine, a tenté de lire une réponse provenant d’une autre origine, et le serveur de cette origine n’a pas envoyé les en-têtes qui l’autorisent. Le navigateur empêche votre code de lire la réponse. La correction se fait côté serveur, ou dans la manière dont la requête est routée, et non dans le code du front-end.

Puis-je corriger une erreur CORS depuis le front-end ?

Pas correctement. Des réglages comme mode: 'no-cors' ne font que masquer la réponse à votre code. Vous corrigez le problème en faisant envoyer au serveur le bon en-tête Access-Control-Allow-Origin, ou en appelant l’API depuis votre propre back end ou un proxy de même origine.

Access-Control-Allow-Origin: * est-il sûr ?

C’est acceptable pour des données publiques que tout le monde peut lire, comme une API publique sans connexion. Cela ne fonctionne pas avec les cookies ni avec d’autres identifiants, et pour une API privée vous devez lister les origines exactes autorisées.

Pourquoi ma requête fonctionne-t-elle dans Postman ou curl mais pas dans le navigateur ?

CORS n’est appliqué que par les navigateurs. Des outils comme Postman et curl ne l’appliquent pas, donc une requête peut réussir là-bas et être tout de même bloquée lorsque le JavaScript de la page la lance.

Qu’est-ce qu’une requête preflight ?

Pour les requêtes qui ne sont pas simples, comme un POST en JSON ou une requête avec un en-tête Authorization, le navigateur envoie d’abord une requête OPTIONS pour demander au serveur quelles méthodes et quels en-têtes sont autorisés. Si cette requête OPTIONS échoue ou n’a pas les bons en-têtes, la vraie requête n’est jamais envoyée.

Mythex · Pricing · Créez tout avec l'IA · Modèles de sites et d'applications · Mythex comparé · Glossaire de la création d'applications avec l'IA · Outils gratuits pour créer des applications avec l'IA · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)