Quel rosso in console che ti rovina la giornata
Apri la console del browser e leggi:
Access to fetch at 'https://api.miosito.com/users' from origin
'https://miosito.com' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the
requested resource.
Chiedi a Claude. Provi 5 fix che peggiorano la situazione. Aggiungi * dappertutto. NO. Fermati.
Cos'è davvero CORS
CORS (Cross-Origin Resource Sharing) non è un bug: è una protezione del browser. Senza CORS, qualsiasi sito malevolo potrebbe far partire richieste autenticate al tuo backend a tua insaputa.
Per il browser, due URL hanno la stessa origine solo se condividono protocollo + dominio + porta. Quindi:
https://miosito.comehttps://miosito.com/api→ stessa origine ✓https://miosito.comehttps://api.miosito.com→ origini diverse ✗http://miosito.comehttps://miosito.com→ origini diverse ✗http://localhost:3000ehttp://localhost:3001→ origini diverse ✗
Se le origini sono diverse, il browser chiede al server se accetta la richiesta. Se il server non risponde con Access-Control-Allow-Origin: https://miosito.com, il browser blocca tutto.
CORS si configura sul SERVER, non sul client
Errore numero 1 del vibecoder: cercare di fixare CORS lato browser. Non si può. Il fix è sempre nel backend.
Express
const cors = require('cors');
app.use(cors({
origin: 'https://miosito.com',
credentials: true // se usi cookie di sessione
}));
Next.js API routes
// app/api/users/route.ts
export async function GET(req: Request) {
return new Response(JSON.stringify({ data }), {
headers: {
'Access-Control-Allow-Origin': 'https://miosito.com',
'Access-Control-Allow-Credentials': 'true',
'Content-Type': 'application/json'
}
});
}
Nginx (reverse proxy)
location /api/ {
add_header 'Access-Control-Allow-Origin' 'https://miosito.com' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
proxy_pass http://127.0.0.1:3000;
}
NON usare mai * in produzione
Access-Control-Allow-Origin: * dice al browser "qualsiasi sito può chiamarmi". Funziona, ma:
- È un buco di sicurezza: chiunque può fare richieste al tuo backend.
- Non funziona con i cookie (
credentials: 'include'). Quindi il login si rompe.
Sempre lista esplicita di origini. Se ne hai 3 (staging + prod + extra), fai una piccola whitelist nel codice.
Il preflight OPTIONS che ti fa impazzire
Per richieste "complesse" (POST con JSON, header custom), il browser manda prima una richiesta OPTIONS di preflight. Se il server non risponde correttamente al preflight, la vera richiesta non parte mai.
Sintomo: nel network tab vedi una richiesta OPTIONS in rosso prima della tua. Quella va fixata, non la POST.
📘 CORS è solo l'inizio
Nel libro Vibecoding Serio il Modulo 7 spiega CORS, HTTPS, cookie httpOnly, JWT, reverse proxy nginx con un'infografica del "viaggio del click in produzione" e prompt-ready per ogni configurazione.
Compra il libro — €14,90→Come parlarne a Claude
Backend Express usa il middleware cors. Mostra come configurarlo per: 1) accettare solo miosito.com (lista whitelist), 2) gestire credentials cookie, 3) rispondere correttamente al preflight OPTIONS, 4) NON usare wildcard.
La regola da portare a casa
CORS è una protezione, non un bug. Si configura sempre sul server, mai sul client, mai con wildcard in produzione, mai senza whitelist esplicita.