Qu'est-ce que CORS et pourquoi est-ce nécessaire ?
CORS (Cross-Origin Resource Sharing) est un mécanisme de sécurité des navigateurs qui bloque par défaut les requêtes HTTP entre domaines différents. Si votre frontend sur app.example.com appelle une API sur api.example.com, le navigateur bloque la requête sauf si le serveur API envoie les bons en-têtes CORS. C'est une protection contre les attaques CSRF, mais elle cause souvent des erreurs frustrantes en développement ("has been blocked by CORS policy").
Comment fonctionnent les requêtes preflight ?
Pour les requêtes "complexes" (PUT, DELETE, ou avec des en-têtes personnalisés), le navigateur envoie d'abord une requête OPTIONS (preflight) pour demander au serveur s'il autorise la requête réelle. Le serveur doit répondre avec les en-têtes Access-Control-Allow-Origin, Access-Control-Allow-Methods et Access-Control-Allow-Headers. Le header Access-Control-Max-Age indique combien de temps le navigateur peut mettre en cache la réponse preflight pour éviter de la répéter à chaque requête.
Erreurs CORS courantes et solutions
L'erreur la plus fréquente est l'absence de l'en-tête Access-Control-Allow-Origin dans la réponse du serveur. Autres pièges courants : utiliser Access-Control-Allow-Origin: * avec Access-Control-Allow-Credentials: true (interdit par les navigateurs), oublier de gérer la méthode OPTIONS pour les preflight, ne pas inclure les en-têtes personnalisés dans Access-Control-Allow-Headers, et configurer CORS côté frontend au lieu du backend (c'est le serveur qui doit envoyer les en-têtes, pas le client).