Ah, CORS ! Ce petit acronyme – Cross-Origin Resource Sharing – est le cauchemar de tout développeur web qui a un jour tenté de faire dialoguer une API frontend avec un backend distant. Vous lancez votre app en local, tout semble parfait en développement, et paf ! Une erreur « CORS policy: No ‘Access-Control-Allow-Origin’ header is present » s’affiche dans la console. Pourquoi CORS « casse tout » ? Dans cet article, on décortique le problème et on vous donne les clés pour le dompter une bonne fois pour toutes.
Qu’est-ce que CORS et pourquoi ça existe ?
CORS est un mécanisme de sécurité intégré aux navigateurs, basé sur la politique same-origin. Imaginez : votre site monapp.com essaie de fetcher des données depuis api.exemple.com. Sans CORS, ce serait la porte ouverte aux attaques comme le CSRF (Cross-Site Request Forgery) ou le vol de données sensibles.
Les navigateurs bloquent par défaut les requêtes cross-origin pour protéger les utilisateurs. Une origine est définie par le protocole (http/https), le domaine et le port. Si l’un diffère, c’est cross-origin, et CORS entre en jeu. Le serveur doit envoyer des en-têtes spécifiques comme Access-Control-Allow-Origin pour autoriser l’accès. Sans ça, votre fetch() ou XMLHttpRequest échoue, même si l’API fonctionne nickel côté serveur.
En résumé, CORS n’est pas un bug : c’est une feature de sécurité. Mais mal gérée, elle stoppe net votre projet.
Les symptômes classiques : quand CORS vous fait ragequitter

Vous reconnaissez le tableau ? Vous codez une app React sur localhost:3000, votre backend Node.js tourne sur localhost:5000, et boom : erreur CORS. Ou pire, en prod, votre frontend hébergé sur Netlify ne peut pas pinguer votre API sur Heroku.
Les coupables habituels :
-
Requêtes simples (GET/POST sans headers custom) : bloquées si pas d’en-têtes CORS sur le serveur.
-
Requêtes préliminaires (preflight) : pour OPTIONS, HEAD, ou avec credentials/custom headers. Le navigateur envoie d’abord une requête OPTIONS pour tester les permissions.
-
Erreurs en console :
"blocked by CORS policy"ou"origin 'null' is not allowed".
Ça « casse tout » car ça impacte le dev local, les déploiements multi-domaines, et même les apps SPA avec micro-frontends. Résultat : heures perdues à debugger. Accédez à toutes les infos en cliquant ici.
Les solutions côté serveur : configurez vos en-têtes comme un pro
Pour dompter CORS, agissez côté serveur. Voici les étapes clés, avec exemples concrets.
1. Ajoutez les en-têtes essentiels
Le minimum :
Access-Control-Allow-Origin: https://monapp.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Pour le dev, utilisez * (attention, pas en prod pour la sécu !).
Exemple Node.js/Express :
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
if (req.method === 'OPTIONS') res.sendStatus(200);
next();
});
2. Gérez les preflights et credentials
Pour les requêtes avec cookies ou auth :
Access-Control-Allow-Credentials: true
Évitez * avec credentials – listez les origines précises.
Pour Nginx/Apache : Ajoutez dans la config serveur :
add_header 'Access-Control-Allow-Origin' 'https://monapp.com';
3. Frameworks populaires
-
Spring Boot :
@CrossOrigin(origins = "http://localhost:3000")sur vos controllers. -
Django : Installez
django-cors-headerset ajoutezCORS_ALLOWED_ORIGINS. -
Laravel : Middleware avec
cors().
Testez avec curl -H "Origin: http://localhost:3000" -X OPTIONS yourapi.com.
Solutions côté client et astuces de contournement
Pas toujours possible de toucher le serveur ? Voici des parades temporaires.
-
Proxy en dev : Pour Create React App, ajoutez
"proxy": "http://localhost:5000"danspackage.json. Vite ?server.proxydansvite.config.js. -
JSONP : Ancienne technique pour GET only (évitez-la, obsolète).
-
Serveur proxy dédié : Utilisez nginx ou un service comme Cloudflare Workers pour router les requêtes.
-
Extensions Chrome : « CORS Unblock » pour dev only (jamais en prod !).
En prod, préférez un reverse proxy (comme Vercel ou AWS API Gateway) qui gère CORS automatiquement.
Bonnes pratiques et pièges à éviter
Pour un CORS zen :
-
Listez les origines précises en prod, pas
*. -
Cachez les preflights avec
Access-Control-Max-Age: 86400. -
HTTPS only : CORS est strict sur les mixed contents.
-
Piège courant :
localhostvs127.0.0.1– ce sont des origines différentes ! -
Outils de debug : Chrome DevTools > Network > filtre CORS, ou cors-test.codehappy.dev.
CORS ne casse plus rien quand on le comprend. Implémentez ces fixes, et votre stack full-stack ronronnera.
Qu’en pensez-vous ? Avez-vous une stack spécifique (React/Node, Vue/Django…) où vous voulez un exemple plus détaillé ?