Tu fais un fetch() vers une API et le navigateur te répond : "Access to fetch has been blocked by CORS policy". Ton code est correct, l'API fonctionne dans Postman, mais le navigateur refuse. Voici pourquoi et comment résoudre ça en 5 minutes.
C'est quoi CORS en 30 secondes ?
CORS (Cross-Origin Resource Sharing) est une sécurité du navigateur. Par défaut, le navigateur interdit à une page web de faire des requêtes vers un domaine différent du sien.
✅ gogokodo.com → gogokodo.com/api (même origine)
❌ gogokodo.com → api.exemple.com (origine différente)
❌ localhost:3000 → localhost:8080 (port différent = origine différente)
Une "origine" = protocole + domaine + port. Si un seul diffère, le navigateur bloque.
Important : c'est le navigateur qui bloque, pas le serveur. C'est pourquoi ça marche dans Postman (pas de navigateur) mais pas dans ton code.
Les 3 erreurs CORS les plus fréquentes
1. "No 'Access-Control-Allow-Origin' header"
La plus courante. Le serveur ne renvoie pas le header qui autorise ta requête.
Access to fetch at 'https://api.exemple.com/data'
from origin 'http://localhost:3000' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Solution serveur (Node/Express) :
const cors = require('cors');
app.use(cors()); // Autorise toutes les origines
// Plus sécurisé — autoriser une origine spécifique
app.use(cors({
origin: 'https://monsite.com'
}));
2. "CORS preflight request failed"
Pour certaines requêtes (POST avec JSON, PUT, DELETE), le navigateur envoie d'abord une requête OPTIONS ("preflight") pour demander la permission.
// Cette requête déclenche un preflight
fetch('https://api.exemple.com/data', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'Ali' })
});
Solution : le serveur doit répondre aux requêtes OPTIONS.
app.use(cors({
origin: 'https://monsite.com',
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization']
}));
3. "Credentials flag is true but..."
Tu envoies des cookies mais le serveur n'est pas configuré pour ça.
// Front
fetch('https://api.exemple.com/data', {
credentials: 'include'
});
// Serveur — doit autoriser les credentials
app.use(cors({
origin: 'https://monsite.com', // ⚠️ Pas '*' avec credentials
credentials: true
}));
Solution côté front (quand tu ne contrôles pas le serveur)
Proxy en développement (Vite)
// vite.config.js
export default defineConfig({
server: {
proxy: {
'/api': {
target: 'https://api.exemple.com',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
}
});
// Ton code — plus de CORS !
fetch('/api/data'); // → proxy vers api.exemple.com/data
Proxy en production
Crée une route API sur TON serveur qui fait la requête vers l'API tierce :
app.get('/api/proxy/data', async (req, res) => {
const response = await fetch('https://api.exemple.com/data');
const data = await response.json();
res.json(data);
});
Ce qu'il ne faut PAS faire
- ❌ Désactiver la sécurité du navigateur (
--disable-web-security) - ❌ Utiliser un proxy CORS public (risque sécurité)
- ❌ Mettre
Access-Control-Allow-Origin: *sur une API avec authentification
Résumé
| Situation | Solution |
|---|---|
| Tu contrôles le serveur |
cors() middleware |
| API tierce en dev | Proxy Vite/Webpack |
| API tierce en prod | Route proxy sur ton serveur |
| Requêtes avec cookies |
credentials: true + origine explicite |
Article original publié sur gogokodo.com
Top comments (0)