Les pubs vous déplaisent ? Aller Sans pub Auj.

CORS Expliqué Comment déboguer les erreurs d'origine cross-domain sans perdre la tête

Publié le
CORS Expliqué : Comment déboguer les erreurs de cross-origin sans perdre la tête 1
ANNONCE · Supprimer ?

Vous avez envoyé une requête fetch. L'onglet Réseau l'affiche comme envoyée. Mais dans la console, il y a un mur de rouge : L'accès à fetch pour l'URL « https://api.example.com » depuis l'origine « https://yourapp.com » a été bloqué par la politique CORS.

Avant de plonger dans les explications — voici le chemin le plus rapide de diagnostic. Ouvrez DevTools → onglet Réseau → trouvez la requête échouée → regardez la En-têtes de réponse. Si vous n'avez pas de Access-Control-Allow-Origin, votre serveur n'envoie pas d'en-têtes CORS. C'est la solution. Le reste de cet article explique exactement ce qu'il faut envoyer et pourquoi.

Ce que représente réellement CORS

CORS — Partage de ressources entre origines — est appliqué par le navigateur, pas par votre serveur. Votre API ne bloque pas automatiquement les requêtes inter-origines. C'est le navigateur qui le fait, au nom des utilisateurs, pour empêcher des scripts sur evil.com de lire silencieusement vos données bancaires.

Le navigateur vérifie : « La réponse de cette API me dit-elle qu’il est autorisé à lire cette origine ? » Si non, elle bloque la réponse — même si le serveur a déjà traité la requête et a retourné un 200. Le serveur ne sait jamais pourquoi le client l'a rejeté.

Cela compte lors du débogage : l'erreur se produit toujours du côté client. Le serveur doit informer le navigateur : « Oui, cette origine est autorisée. » C'est ce que font les en-têtes de réponse CORS.

Requêtes simples vs requêtes prévues

Pas toutes les requêtes inter-origines se comportent de la même manière. Le navigateur distingue deux types.

Requêtes simples sont des requêtes GET ou POST avec des corps simples (texte brut ou form-encoded) et un petit ensemble d'en-têtes autorisés. Le navigateur les envoie directement et vérifie la réponse pour Access-Control-Allow-Origin.

Requêtes prévues se produisent avant lorsque votre requête ne répond pas à ces conditions — par exemple, si vous envoyez un PUT ou DELETE, que vous incluez un en-tête personnalisé comme Authorization ou Content-Type: application/json, ou que vous envoyez des informations de connexion. Le navigateur lance automatiquement une requête OPTIONS vers la même URL avant votre requête réelle. Si le serveur ne répond pas à cette OPTIONS requête avec les bonnes en-têtes CORS, votre requête réelle ne part jamais.

Si vous voyez des OPTIONS requêtes dans votre onglet Réseau qui retournent 404 ou 405, c'est pourquoi vos requêtes échouent. Votre serveur doit gérer OPTIONS pour chaque route qui reçoit du trafic inter-origine.

Les en-têtes qui comptent

Pour bien configurer les en-têtes CORS, il faut comprendre ce que chaque en-tête de réponse contrôle exactement :

  • Access-Control-Allow-Origin — les origines autorisées à lire la réponse. Soit une origine précise (https://yourapp.com) soit * pour toute origine.
  • Access-Control-Allow-Methods — les méthodes HTTP autorisées (par exemple, GET, POST, PUT, DELETE, OPTIONS).
  • Access-Control-Allow-Headers — les en-têtes de requête autorisés (par exemple, Authorization, Content-Type).
  • Access-Control-Allow-Credentials — la possibilité d'envoyer des cookies et des en-têtes d'authentification avec la requête. Doit être true explicitement.
  • Access-Control-Max-Age — la durée en secondes pendant laquelle le navigateur doit conserver la réponse prévue.

Le piège du caractère générique

L'utilisation de Access-Control-Allow-Origin: * est la méthode la plus rapide pour ouvrir votre API — mais elle échoue dès que vous ajoutez des informations de connexion. Quand Access-Control-Allow-Credentials: true est requise, le caractère générique est rejeté par le navigateur. Vous devez spécifier l'origine exacte :

# This will fail with credentials:
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

# This works:
Access-Control-Allow-Origin: https://yourapp.com
Access-Control-Allow-Credentials: true

Si vous avez plusieurs origines autorisées, lisez l'en-tête Origin de la requête et répétez-le conditionnellement — ne les concaténez pas.

Erreurs courantes de CORS et ce qu'elles signifient

Le message d'erreur du navigateur indique généralement ce qui manque. Voici une référence rapide :

Message d'erreurCe que cela signifieComment le corriger
Aucun en-tête « Access-Control-Allow-Origin » n'est présentLe serveur n'a pas envoyé d'en-têtes CORSAjouter Access-Control-Allow-Origin à la réponse
La valeur de l'en-tête « Access-Control-Allow-Origin » … ne correspond pas à l'origine fournieMauvaise correspondance de l'origine — le serveur a retourné une origine incorrecte ou générique avec des informations de connexionRépétez l'en-tête d'origine de la requête conditionnellement ; supprimez le caractère générique quand des informations de connexion sont utilisées
La méthode PUT n'est pas autorisée par l'en-tête « Access-Control-Allow-Methods »La méthode HTTP n'est pas listée dans l'en-tête des méthodes autoriséesAjoutez la méthode manquante à Access-Control-Allow-Methods
L'en-tête de requête « Authorization » n'est pas autorisée par l'en-tête « Access-Control-Allow-Headers »L'en-tête personnalisée n'est pas présente dans la liste autoriséeAjoutez l'en-tête à Access-Control-Allow-Headers
La réponse à la requête prévue ne passe pas le contrôle d'accèsLa requête OPTIONS a retourné un statut incorrect ou des en-têtes manquantsGérez explicitement la requête OPTIONS ; retournez 200/204 avec les bonnes en-têtes
Les informations de connexion ne sont pas supportées si l'en-tête CORS « Access-Control-Allow-Origin » est « * »Utilisation du caractère générique avec le mode de connexionRemplacez * par l'origine précise ; ajoutez Access-Control-Allow-Credentials: true

Comment configurer CORS dans Express, FastAPI et Nginx

Express (Node.js)

const cors = require('cors');

app.use(cors({
  origin: 'https://yourapp.com',
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  credentials: true,
  maxAge: 86400
}));

// Handle preflight for all routes
app.options('*', cors());

FastAPI (Python)

from fastapi.middleware.cors import CORSMiddleware

app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://yourapp.com"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

Nginx

location /api/ {
    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' 'https://yourapp.com';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Max-Age' 86400;
        add_header 'Content-Length' 0;
        return 204;
    }

    add_header 'Access-Control-Allow-Origin' 'https://yourapp.com';
    add_header 'Access-Control-Allow-Credentials' 'true';

    proxy_pass http://backend;
}

Notez le modèle Nginx : vous avez besoin de add_header dans les deux blocs, le bloc OPTIONS et le bloc principal. Les en-têtes définis dans if ne sont pas transmis au bloc externe.

Votre checklist de débogage

Quand vous rencontrez une erreur CORS, procédez ainsi :

  1. Lisez le message d'erreur complet — il vous indique exactement quel en-tête ou quelle valeur est incorrecte.
  2. Vérifiez l'onglet Réseau — regardez les en-têtes de réponse réels, pas ce que vous avez configuré.
  3. Vérifiez la présence d'une requête OPTIONS — si elle échoue ou est absente, votre serveur ne gère pas la requête prévue.
  4. Vérifiez que l'origine correspond exactement — les barres finales, HTTP vs HTTPS, et les numéros de port comptent.
  5. Supprimez le caractère générique si vous utilisez des informations de connexion — ils sont mutuellement exclusifs.
  6. Vérifiez que les en-têtes ne sont pas supprimés par un proxy — Nginx et les CDN peuvent parfois supprimer ou remplacer les en-têtes CORS.

Un piège facile à manquer : si votre API se trouve derrière un proxy inverse ou un CDN, cette couche peut ajouter son propre en-tête Access-Control-Allow-Origin qui entre en conflit avec ce que retourne votre serveur. Quand deux de ces en-têtes apparaissent dans une même réponse, le navigateur rejette l'ensemble. Vérifiez toujours les en-têtes de réponse bruts au niveau du réseau — pas seulement ce que votre code d'application envoie.

Autre cas limite : certains frameworks n'ajoutent pas d'en-têtes CORS aux routes qui correspondent à un gestionnaire enregistré. Si vous atteignez un 404 ou une route non enregistrée, le middleware CORS peut ne jamais s'exécuter, et vous verrez l'erreur « aucun en-tête présent » même si votre configuration semble correcte. Testez d'abord avec une route valide.

Si vous avez besoin de générer rapidement les en-têtes CORS exacts que votre serveur doit retourner, le IO Tools CORS Headers Builder vous permet de configurer l'origine, les méthodes et les informations de connexion, et génère le bloc d'en-tête correct à coller dans votre configuration du serveur.

Une remarque sur la sécurité

CORS n'est pas un mécanisme de sécurité pour une API. Le fait de mettre Access-Control-Allow-Origin: * ne rend pas votre API publique d'un point de vue pertinent en matière de surface d'attaque — curl, Postman, et les appels entre serveurs ne sont jamais soumis aux restrictions CORS. Seulement les appels via JavaScript sont concernés. Si votre API nécessite une authentification, imposez-la au niveau de l'API avec des tokens ou des sessions. Les en-têtes CORS indiquent simplement aux navigateurs quelles origines sont autorisées à lire les réponses à partir de JavaScript. Ils sont orthogonaux au contrôle d'accès réel.

Avec ce contexte, vous pouvez prendre des décisions sensées concernant votre configuration CORS, plutôt que de laisser tout le monde entrer par crainte de sécurité ou de laisser tout ouvert sans comprendre les compromis.

Envie d'une expérience sans pub ? Passez à la version sans pub

Installez nos extensions

Ajoutez des outils IO à votre navigateur préféré pour un accès instantané et une recherche plus rapide

Sur Extension Chrome Sur Extension de bord Sur Extension Firefox Sur Extension de l'opéra

Le Tableau de Bord Est Arrivé !

Tableau de Bord est une façon amusante de suivre vos jeux, toutes les données sont stockées dans votre navigateur. D'autres fonctionnalités arrivent bientôt !

ANNONCE · Supprimer ?
ANNONCE · Supprimer ?
ANNONCE · Supprimer ?

Coin des nouvelles avec points forts techniques

Impliquez-vous

Aidez-nous à continuer à fournir des outils gratuits et précieux

Offre-moi un café
ANNONCE · Supprimer ?