Se ti sei imbattuto nell'errore Access to fetch at '...' has been blocked by CORS policy nella console del browser, conosci bene la frustrazione. Gli errori CORS sono tra le problematiche più frequenti nello sviluppo web moderno, eppure il meccanismo sottostante viene spesso frainteso. Questa guida approfondisce il funzionamento del CORS per aiutarti a risolvere i blocchi e comprendere le ragioni di sicurezza dietro questo protocollo.
Che cos'è la Same-Origin Policy (SOP)?
I browser applicano una politica di sicurezza fondamentale chiamata Same-Origin Policy (SOP). Due URL sono considerati della "stessa origine" solo se condividono identico protocollo, hostname e porta.
https://example.com/pagina1 → https://example.com/pagina2 ✅ Stessa origine https://example.com → http://example.com ❌ Protocollo diverso https://example.com → https://api.example.com ❌ Hostname diverso https://example.com → https://example.com:8080 ❌ Porta diversa
La SOP impedisce a un sito malevolo di leggere dati riservati da un altro sito. Senza questa protezione, qualsiasi sito potrebbe effettuare chiamate all'API della tua banca utilizzando i cookie salvati nel tuo browser.
Cos'è il CORS?
Il CORS (Cross-Origin Resource Sharing) è un meccanismo che allenta le restrizioni della SOP in modo controllato. Permette al server di dichiarare esplicitamente quali origini esterne sono autorizzate ad accedere alle proprie risorse, utilizzando specifici header HTTP.
Come funziona il CORS
Richieste Semplici (Simple Requests)
Per le richieste GET o POST standard con header limitati, il browser esegue la chiamata direttamente e verifica la presenza degli header di autorizzazione nella risposta:
// Il browser invia:
GET /api/dati HTTP/1.1
Host: api.example.com
Origin: https://miapp.com
// Il server risponde:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://miapp.com
Content-Type: application/json
{"dati": "..."}
Richieste Preflight (OPTIONS)
Per richieste "non semplici" (che includono metodi come PUT/DELETE, header personalizzati o il tipo JSON), il browser invia prima una richiesta di verifica OPTIONS, detta preflight, per chiedere il permesso al server.
// 1. Il browser richiede il preflight: OPTIONS /api/utenti HTTP/1.1 Host: api.example.com Origin: https://miapp.com Access-Control-Request-Method: DELETE Access-Control-Request-Headers: Content-Type, Authorization // 2. Il server risponde indicando cosa è consentito: HTTP/1.1 204 No Content Access-Control-Allow-Origin: https://miapp.com Access-Control-Allow-Methods: GET, POST, PUT, DELETE Access-Control-Allow-Headers: Content-Type, Authorization Access-Control-Max-Age: 86400 // 3. Il browser invia la richiesta reale solo se il preflight è positivo
Header CORS Fondamentali
Access-Control-Allow-Origin: https://miapp.com // Origine autorizzata Access-Control-Allow-Methods: GET, POST, PUT // Metodi HTTP consentiti Access-Control-Allow-Headers: Content-Type, Auth // Header personalizzati permessi Access-Control-Allow-Credentials: true // Abilita cookie/auth Access-Control-Max-Age: 86400 // Cache preflight (secondi) Access-Control-Expose-Headers: X-Request-Id // Header leggibili via JS
Configurazioni lato Server
import cors from 'cors';
app.use(cors({
origin: ['https://miapp.com', 'https://staging.miapp.com'],
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true,
maxAge: 86400
}));
location /api/ {
add_header Access-Control-Allow-Origin "https://miapp.com" always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE" always;
add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
if ($request_method = OPTIONS) {
return 204;
}
}
header("Access-Control-Allow-Origin: https://miapp.com");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE");
header("Access-Control-Allow-Headers: Content-Type, Authorization");
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(204);
exit;
}
Errori CORS comuni
- Usare
Access-Control-Allow-Origin: *con credenziali: Il browser bloccherà la richiesta. Quandocredentials: true, devi specificare un'origine esatta. - CORS è una protezione lato browser: Non protegge le tue API da chiamate server-to-server. Implementa sempre l'autenticazione su ogni endpoint.
- Dimenticare il flag
alwaysin Nginx: Senza di esso, gli header CORS mancheranno nelle risposte di errore (4xx, 5xx), causando fallimenti durante il debugging. - Ignorare le richieste OPTIONS: Se il server risponde con 404 o 405 alle richieste preflight, l'intera comunicazione verrà interrotta dal browser.
Prova i nostri Strumenti Gratuiti
Codifica URL, decodifica Base64 e formatta i file JSON in un istante.