CORS : pourquoi ça casse tout (et comment le dompter)

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 :

text
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 :

javascript
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 :

text
Access-Control-Allow-Credentials: true

Évitez * avec credentials – listez les origines précises.

Pour Nginx/Apache : Ajoutez dans la config serveur :

text
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-headers et ajoutez CORS_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" dans package.json. Vite ? server.proxy dans vite.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 : localhost vs 127.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é ?

Articles Similaires