DEV Community

ahmed SENEINA
ahmed SENEINA

Posted on • Originally published at gogokodo.com

Erreur CORS Bloqué : Comprendre et Résoudre en 5 Minutes

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)
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode

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'
}));
Enter fullscreen mode Exit fullscreen mode

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' })
});
Enter fullscreen mode Exit fullscreen mode

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']
}));
Enter fullscreen mode Exit fullscreen mode

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
}));
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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);
});
Enter fullscreen mode Exit fullscreen mode

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)