Back

Comprendre CORS : Pourquoi votre requête a échoué

Comprendre CORS : Pourquoi votre requête a échoué

Lorsque votre application JavaScript génère une erreur CORS, ce n’est pas un problème de code défectueux—c’est le navigateur qui protège les utilisateurs contre des menaces de sécurité potentielles. Comprendre pourquoi ces erreurs se produisent nécessite de saisir le modèle de sécurité fondamental qui régit la façon dont les navigateurs gèrent les requêtes cross-origin.

Points clés à retenir

  • Les erreurs CORS se produisent lorsque les navigateurs bloquent des requêtes cross-origin qui ne disposent pas des autorisations serveur appropriées
  • La Same-Origin Policy protège les utilisateurs en restreignant les requêtes entre différentes origines
  • Les requêtes simples s’exécutent directement tandis que les requêtes complexes nécessitent une vérification preflight OPTIONS
  • Le débogage CORS nécessite d’examiner les onglets réseau du navigateur et de vérifier les en-têtes de réponse du serveur

Les fondements de la Same-Origin Policy

Les navigateurs appliquent la Same-Origin Policy (politique de même origine) comme mécanisme de sécurité principal. Une origine se compose de trois parties : le protocole (https://), le domaine (example.com) et le port (:3000). Lorsque ces éléments correspondent exactement, les requêtes circulent librement. Lorsqu’ils diffèrent—même légèrement—vous effectuez une requête cross-origin.

Considérez ces origines :

  • https://app.example.comhttps://api.example.com (sous-domaine différent = origine différente)
  • http://localhost:3000http://localhost:3001 (port différent = origine différente)
  • http://example.comhttps://example.com (protocole différent = origine différente)

Sans cette politique, n’importe quel site web pourrait lire votre Gmail, accéder à vos données bancaires ou effectuer des requêtes en votre nom. Cross-Origin Resource Sharing (CORS) offre un assouplissement contrôlé de ces restrictions.

Comment les navigateurs appliquent CORS

Le navigateur agit comme exécuteur, pas le serveur. Cette distinction est importante car elle explique des idées reçues courantes :

  1. « Ça fonctionne dans Postman/curl » - Ces outils ne sont pas des navigateurs ; ils n’appliquent pas CORS
  2. « Ajouter le mode no-cors va résoudre le problème » - Cela ne désactive pas CORS ; cela crée une réponse opaque que vous ne pouvez pas lire
  3. « Le serveur bloque ma requête » - Le serveur répond normalement ; c’est le navigateur qui bloque l’accès à la réponse

Lorsque vous effectuez une requête cross-origin, le navigateur ajoute automatiquement un en-tête Origin. Le serveur doit répondre avec un en-tête Access-Control-Allow-Origin qui correspond à votre origine (ou * pour les ressources publiques). L’absence d’en-tête correspondant signifie que le navigateur bloque l’accès à la réponse—d’où votre erreur CORS.

Requêtes simples vs. requêtes preflight

Toutes les requêtes ne déclenchent pas le même comportement CORS. Les requêtes simples passent immédiatement, tandis que d’autres nécessitent une requête preflight.

Requêtes simples (sans preflight)

Ces requêtes répondent à TOUS ces critères :

  • Méthode : GET, HEAD ou POST
  • En-têtes : Uniquement des en-têtes simples (Accept, Content-Language, Content-Type)
  • Content-Type : Uniquement application/x-www-form-urlencoded, multipart/form-data ou text/plain

Requêtes déclenchant un preflight

Toute requête qui ne respecte pas les critères simples déclenche un preflight OPTIONS :

  • Méthodes comme PUT, DELETE, PATCH
  • En-têtes personnalisés (Authorization, X-API-Key)
  • Content-Type: application/json (oui, JSON déclenche un preflight)

Le preflight demande l’autorisation avant d’envoyer votre requête réelle. Le serveur doit répondre avec les en-têtes appropriés :

  • Access-Control-Allow-Methods (quelles méthodes sont autorisées)
  • Access-Control-Allow-Headers (quels en-têtes sont permis)
  • Access-Control-Max-Age (combien de temps mettre en cache cette autorisation)

Points de défaillance CORS courants

En-têtes manquants ou incorrects

Le serveur ne renvoie aucun en-tête Access-Control-Allow-Origin, ou celui-ci ne correspond pas à votre origine. Rappel : http://localhost:3000 et http://localhost:3001 sont des origines différentes.

Contraintes liées aux credentials

L’inclusion de credentials (credentials: 'include' ou withCredentials: true) ajoute des restrictions :

  • Le serveur doit inclure Access-Control-Allow-Credentials: true
  • Access-Control-Allow-Origin ne peut pas être *—il doit spécifier votre origine exacte
  • Les cookies doivent respecter les exigences SameSite

Complications liées aux redirections

CORS et les redirections interagissent mal. Une redirection vers une origine différente pendant une requête CORS échoue souvent car le navigateur ne gère pas correctement le changement d’origine. Évitez les redirections cross-origin dans les requêtes CORS.

Accès aux réseaux privés

Les navigateurs modernes ajoutent une protection supplémentaire lorsque des sites web publics accèdent à des ressources de réseaux privés (localhost, 192.168.x.x, 10.x.x.x). Ces requêtes peuvent nécessiter des en-têtes supplémentaires comme Access-Control-Allow-Private-Network et déclencher un preflight même pour des requêtes simples. Cette protection empêche les sites web externes de scanner votre réseau local.

Déboguer CORS efficacement

Face aux erreurs CORS :

  1. Vérifiez l’onglet Réseau du navigateur - Recherchez la requête preflight OPTIONS et examinez les en-têtes de requête et de réponse
  2. Vérifiez le message d’erreur exact - « En-tête CORS ‘Access-Control-Allow-Origin’ manquant » vs. « L’en-tête CORS ‘Access-Control-Allow-Origin’ ne correspond pas » pointent vers des problèmes différents
  3. Testez d’abord sans credentials - Supprimez credentials: 'include' pour isoler les problèmes liés aux credentials
  4. Confirmez la correspondance de l’origine - Assurez-vous que le protocole, le domaine et le port correspondent tous exactement

Conclusion

Les erreurs CORS ne sont pas des obstacles arbitraires—c’est le navigateur qui protège les utilisateurs contre des requêtes cross-origin malveillantes. Le serveur déclare quelles origines peuvent accéder à ses ressources via les en-têtes CORS, et le navigateur applique ces règles. Comprendre ce modèle transforme CORS d’un bloqueur mystérieux en un système prévisible que vous pouvez déboguer méthodiquement.

Lorsque votre requête échoue, vérifiez s’il s’agit d’une requête simple ou preflight, vérifiez que les en-têtes CORS du serveur correspondent exactement à votre origine, et rappelez-vous que des outils comme Postman contournent complètement ces vérifications. Le navigateur fait son travail—votre tâche consiste à vous assurer que le serveur fournit les autorisations correctes.

FAQ

Postman et les autres outils de test d'API n'appliquent pas les politiques CORS. Seuls les navigateurs implémentent ces restrictions de sécurité. Votre serveur doit envoyer les en-têtes Access-Control-Allow-Origin appropriés pour que les requêtes du navigateur réussissent.

Bien que les navigateurs offrent des options pour désactiver les fonctionnalités de sécurité, c'est risqué et affecte tous les sites. À la place, configurez votre serveur de développement pour envoyer les en-têtes CORS appropriés ou utilisez un serveur proxy pour gérer les requêtes cross-origin pendant le développement.

La spécification CORS ne considère que trois types de contenu comme simples : application/x-www-form-urlencoded, multipart/form-data et text/plain. Tout autre type de contenu, y compris application/json, déclenche une requête preflight OPTIONS pour vérifier les autorisations.

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before 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.

OpenReplay