Guide

Come risolvere gli errori CORS (e perché si verificano)

Un errore CORS significa che la tua pagina web ha provato a leggere una risposta da un'altra origine (un altro dominio, porta o protocollo), e quel server non ha inviato intestazioni che lo consentono. I browser bloccano la risposta per proteggere gli utenti. Lo risolvi sul server, restituendo un'intestazione Access-Control-Allow-Origin per l'origine del tuo sito e gestendo le richieste preflight OPTIONS, oppure lo eviti inviando la richiesta tramite il tuo back end sulla stessa origine.

È uno degli errori più confusi dello sviluppo web, perché la richiesta spesso arriva al server senza problemi. Questa guida spiega cosa succede e come risolvere ciascuna variante.

Cosa significa "origine"

Un'origine è la combinazione di protocollo, dominio e porta:

URLOrigine
https://miaapp.com/dashboardhttps://miaapp.com
https://api.miaapp.com/usershttps://api.miaapp.com (sottodominio diverso, quindi origine diversa)
http://localhost:5173http://localhost:5173
http://localhost:3000http://localhost:3000 (porta diversa, quindi origine diversa)

I browser seguono la same-origin policy: il JavaScript di una pagina può leggere liberamente le risposte della propria origine, ma non quelle di altre. CORS (Cross-Origin Resource Sharing) è il sistema che permette a un server di acconsentire: "le risposte da me possono essere lette dalle pagine di queste origini".

Due conseguenze sorprendono molti:

  • La richiesta spesso arriva al server. CORS di solito impedisce al tuo codice di leggere la risposta, non impedisce al server di ricevere la richiesta. Un POST può essere stato salvato anche se hai visto un errore.
  • Solo i browser lo applicano. curl, Postman e il codice lato server ignorano completamente CORS. Per questo "funziona in Postman" non dice nulla su CORS.

Passo 1: leggi l'errore esatto

Apri gli strumenti per sviluppatori (clic destro → Ispeziona), vai alla Console e leggi il messaggio completo. La formulazione di Chrome ti dice quale problema hai:

Il messaggio contieneCosa non va
No 'Access-Control-Allow-Origin' header is presentIl server non ha inviato affatto l'intestazione, oppure la richiesta è fallita prima di raggiungere il tuo codice CORS (per esempio un 404 o un 500)
The 'Access-Control-Allow-Origin' header has a value '...' that is not equal to the supplied originIl server consente un'origine diversa dalla tua
Response to preflight request doesn't pass access control checkLa richiesta preflight OPTIONS è fallita
...must not be the wildcard '*' when the request's credentials mode is 'include'Stai inviando cookie, e il server ha risposto con *
Request header field authorization is not allowedIl server non ha elencato quell'intestazione in Access-Control-Allow-Headers

Poi apri la scheda Rete, trova la richiesta che fallisce (e le eventuali richieste OPTIONS prima di essa), e guarda il suo codice di stato e le intestazioni della risposta.

Controlla prima il codice di stato. Molti "errori CORS" sono in realtà un errore del server travestito. Se il server va in crash o restituisce un 404, la sua risposta d'errore spesso non ha intestazioni CORS, quindi il browser segnala CORS invece del vero problema. Correggi il 500 o il 404, e l'errore CORS può sparire.

Passo 2: decidi se dovresti chiamare quell'API dal browser

Prima di aggiungere intestazioni, chiediti: il browser dovrebbe chiamare direttamente questa API?

  • Un'API di terze parti che richiede una chiave segreta (OpenAI, la chiave segreta di Stripe, la maggior parte dei servizi email) non dovrebbe mai essere chiamata dal browser. La chiave sarebbe visibile a ogni visitatore. Chiamala dal tuo back end, e il problema CORS scompare, perché le richieste server-to-server non sono soggette a CORS. Vedi come proteggere le chiavi API.
  • Un'API di terze parti che non controlli e che non invia intestazioni CORS non può essere risolta dal tuo lato. Chiamala dal tuo back end.
  • La tua API può essere risolta configurandola correttamente. Continua sotto.

Passo 3: correggi il server

Il server deve aggiungere le intestazioni giuste alle sue risposte, incluse quelle d'errore.

Per la richiesta vera, invia:

  • Access-Control-Allow-Origin: https://miaapp.com (l'origine esatta del tuo front end, senza slash finale)
  • Vary: Origin, se il valore dipende da quale origine ha fatto la richiesta

Per la richiesta preflight OPTIONS, rispondi con uno stato di successo (200 o 204) e:

  • Access-Control-Allow-Origin: https://miaapp.com
  • Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE
  • Access-Control-Allow-Headers: Content-Type, Authorization (ogni intestazione personalizzata che invii)
  • Facoltativo Access-Control-Max-Age: 600, così il browser mette in cache il preflight per un po'

La maggior parte dei framework ha un pacchetto o un'impostazione che fa questo. In Express, il pacchetto cors; in FastAPI, CORSMiddleware; in ASP.NET Core, AddCors; in Spring, @CrossOrigin o una configurazione CORS. Un esempio tipico con Express:

import cors from "cors";

app.use(cors({
  origin: ["https://miaapp.com", "http://localhost:5173"],
  credentials: true,
}));

Metti la gestione CORS prima delle tue route e dell'autenticazione, così le richieste preflight (che non portano alcun login) non vengono respinte con un 401.

Con un builder AI, descrivi la configurazione con precisione:

Il front end su https://miaapp.com chiama l'API su https://api.miaapp.com e riceve "Response to preflight request doesn't pass access control check". Configura CORS sull'API per consentire esattamente https://miaapp.com e l'origine dell'anteprima, consenti GET, POST, PATCH, DELETE con le intestazioni Content-Type e Authorization, gestisci OPTIONS prima dell'autenticazione, e includi le intestazioni CORS anche nelle risposte d'errore.

Passo 4: gestisci cookie e credenziali

Se il front end invia cookie (per esempio una sessione di login) a un'altra origine, entrambi i lati devono essere d'accordo:

  • Il front end imposta credentials: "include" su fetch, oppure withCredentials: true in axios.
  • Il server invia Access-Control-Allow-Credentials: true.
  • Il Access-Control-Allow-Origin del server deve essere l'origine esatta, non *.

I cookie cross-site richiedono anche SameSite=None; Secure sul cookie, e alcuni browser limitano ulteriormente i cookie di terze parti. È un altro motivo per preferire l'approccio del passo 5.

Passo 5: evita CORS con una configurazione same-origin

Spesso la soluzione più pulita è non fare affatto richieste cross-origin. Servi l'API dalla stessa origine della pagina, per esempio su https://miaapp.com/api/...:

  • In sviluppo, la maggior parte dei dev server può fare da proxy. L'opzione server.proxy di Vite può inoltrare /api al tuo back end su un'altra porta, così il browser parla sempre con una sola origine.
  • In produzione, instrada /api verso il back end tramite le impostazioni di rewrite o proxy del tuo host, oppure servi front end e API dallo stesso server.

Il front end chiama poi un percorso relativo come fetch("/api/orders"). Non c'è alcuna richiesta cross-origin, nessun preflight tra origini e nessun problema di cookie. Significa anche che non scrivi nel codice un dominio API che cambia tra anteprima e produzione.

Cambia il front end perché chiami il back end con percorsi relativi /api invece di un URL completo, e imposta un proxy di sviluppo così che /api inoltri al server API. Poi rimuovi le impostazioni CORS che non servono più.

Cosa non fare

  • mode: "no-cors" in fetch. Non aggira nulla; ti dà una risposta vuota e illeggibile.
  • Estensioni del browser che disattivano CORS. Cambiano solo il tuo browser. Ogni visitatore vede comunque l'errore.
  • Servizi pubblici di "proxy CORS" per app reali. Possono leggere e modificare tutto ciò che passa attraverso di loro, e a volte vanno giù.
  • Access-Control-Allow-Origin: * su un'API che usa login. Non funziona comunque con le credenziali, ed è il default sbagliato per i dati privati.
  • Riflettere qualsiasi header Origin indietro con le credenziali consentite. Permette a qualsiasi sito di fare richieste autenticate per conto dei tuoi utenti. Usa una lista di origini consentite.

Cause comuni nelle app create con l'AI

SituazioneSoluzione
Il front end chiama un'API di terze parti con una chiave segretaSposta la chiamata nel back end
Funziona nell'anteprima, non sul dominio pubblicatoAggiungi alla lista consentita le origini del dominio pubblicato e di quello personalizzato, oppure usa percorsi relativi /api
Errore solo su POST, PUT o DELETEPreflight non gestito; aggiungi la gestione di OPTIONS e le intestazioni consentite
L'errore è comparso dopo aver aggiunto il loginLe credenziali richiedono un'origine esatta e Allow-Credentials
"Errore CORS" ma la scheda Rete mostra 500Correggi prima l'errore del server
URL dell'API fisso su localhostUsa percorsi relativi o un'impostazione per ambiente

CORS in Mythex

Quando un progetto Mythex ha un sito e un server API, entrambi girano come servizi nello stesso progetto, e puoi passare dall'uno all'altro nell'anteprima. Chiedere all'agente di far chiamare al front end il back end tramite un percorso relativo /api, con proxy in sviluppo, evita la maggior parte dei problemi CORS. Se hai davvero bisogno di chiamate tra origini, fornisci all'agente l'errore esatto della console e le origini coinvolte. Verifica il risultato anche sull'app pubblicata, perché il suo indirizzo è diverso dall'anteprima. Vedi Servizi multipli e Back end API nella documentazione, e le nostre guide su come fare debug di un'app creata con l'AI e front end contro back end.

Checklist CORS

  • Letto il messaggio completo della console e il codice di stato della richiesta che fallisce
  • Escluso un 404 o un 500 nascosto
  • API con chiave segreta chiamate dal back end, non dal browser
  • Il server invia Access-Control-Allow-Origin con le origini esatte consentite
  • Preflight OPTIONS gestito con metodi e intestazioni consentiti, prima dell'autenticazione
  • Intestazioni CORS presenti anche nelle risposte d'errore
  • Credenziali: origine esatta, Allow-Credentials: true, impostazioni dei cookie corrette
  • Origini dell'anteprima, del pubblicato e del dominio personalizzato tutte coperte, oppure percorsi relativi /api usati
  • Nessuna scorciatoia con no-cors, proxy pubblici o riflessione di qualsiasi origine

Domande

Cosa significa un errore CORS?

La tua pagina, caricata da un'origine, ha provato a leggere una risposta da un'altra origine, e quel server non includeva le intestazioni che lo consentono. Il browser impedisce al tuo codice di leggere la risposta. La soluzione è sul server, o nel modo in cui la richiesta viene instradata, non nel codice front end.

Posso risolvere un errore CORS dal front end?

Non in modo corretto. Impostazioni come mode: 'no-cors' nascondono soltanto la risposta al tuo codice. Lo risolvi facendo inviare al server l'intestazione Access-Control-Allow-Origin corretta, oppure chiamando l'API dal tuo back end o da un proxy sulla stessa origine.

Access-Control-Allow-Origin: * è sicuro?

Va bene per dati pubblici che chiunque può leggere, come un'API pubblica senza login. Non può essere usata con cookie o altre credenziali, e per le API private dovresti elencare le origini esatte consentite.

Perché la richiesta funziona in Postman o curl ma non nel browser?

CORS è applicato solo dai browser. Strumenti come Postman e curl non lo applicano, quindi una richiesta può andare a buon fine lì e comunque essere bloccata quando il JavaScript della pagina la invia.

Cos'è una richiesta preflight?

Per le richieste non semplici, come un POST JSON o una richiesta con un'intestazione Authorization, il browser invia prima una richiesta OPTIONS per chiedere al server quali metodi e intestazioni sono consentiti. Se quella richiesta OPTIONS fallisce o non ha le intestazioni giuste, la richiesta vera non viene mai inviata.

Mythex · Pricing · Crea qualsiasi cosa con l'AI · Template per siti web e app · Mythex a confronto · Glossario per creare app con l'AI · Strumenti gratuiti per creare app con l'AI · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)