---
term: 'Cross-Origin Resource Sharing (CORS)'
seoTitle: 'CORS: che cos''è, errori, preflight e correzioni'
headline: 'Che cos''è CORS (Cross-Origin Resource Sharing)?'
slug: cors
category: api-realtime
shortDefinition: 'CORS è un meccanismo del browser con cui un server dichiara quali altre origin possono chiamarlo, allentando di proposito la same-origin policy.'
relatedTerms:
  - api-key-security
  - api-gateway-architecture
  - cross-site-scripting-xss-prevention
contrastsWith:
  - cross-site-scripting-xss-prevention
faq:
  - question: 'Che cos''è CORS in parole semplici?'
    answer: 'Il sistema di permessi del browser per le chiamate API fra siti diversi. Per impostazione predefinita, gli script di un''origin non possono leggere le risposte di un''altra: è la Same-Origin Policy. CORS è il modo in cui un server dà il proprio consenso: header di risposta che dichiarano quali origin, metodi e header accetta. Il browser impone; il server dichiara; il codice frontend è solo il messaggero.'
  - question: 'Che cos''è esattamente un''origin?'
    answer: 'La tripletta schema, host e porta. https://app.example.com e https://api.example.com sono origin diverse (differisce l''host); lo sono anche le versioni http e https di uno stesso sito (differisce lo schema) e :3000 vs :8080 in sviluppo (differisce la porta). La parola inglese indica appunto l''origine di una pagina: ogni decisione CORS confronta queste tre parti, e nient''altro dell''URL conta.'
  - question: 'Che cosa provoca il classico errore CORS?'
    answer: 'Il browser ha chiamato un''altra origin e la risposta non conteneva un header Access-Control-Allow-Origin corrispondente: il browser ha quindi impedito allo script di leggerla. Spesso la richiesta ha raggiunto il server senza problemi; il blocco avviene lato client, sulla lettura. È per questo che la correzione sta sempre nella configurazione del server, mai nel codice frontend.'
  - question: 'Che cos''è una richiesta preflight?'
    answer: 'Il controllo di permesso che il browser esegue in anticipo per le richieste non semplici: prima di inviare un PUT, un DELETE o qualsiasi cosa con header personalizzati come un token di autorizzazione, invia una richiesta OPTIONS che chiede "posso?". Gli header del server rispondono quali metodi, header e origin sono consentiti; solo allora parte la richiesta vera. I preflight si possono mettere in cache con Access-Control-Max-Age.'
  - question: 'Perché una richiesta funziona con curl e fallisce nel browser?'
    answer: 'Perché CORS è un vincolo imposto dal browser, non un rifiuto del server. Strumenti come curl e le app mobile native non hanno una same-origin policy, quindi leggono la risposta senza batter ciglio. Il browser applica la politica per conto della persona che lo usa: la differenza che si osserva è il punto di applicazione, ed è anche la prova che CORS non è controllo degli accessi.'
  - question: 'Access-Control-Allow-Origin: * è sicuro?'
    answer: 'Per API davvero pubbliche e senza credentials, sì. Il wildcard è vietato in modalità con credentials – i browser rifiutano per progetto di associarvi i cookie – e riflettere origin arbitrarie consentendo al tempo stesso i credentials è la configurazione errata classica che trasforma CORS da scudo in falla. Le API private elencano le origin in modo esplicito.'
  - question: 'Si può semplicemente disattivare CORS per risolvere l''errore?'
    answer: 'Solo nel senso in cui togliere il rilevatore di fumo spegne un incendio. I flag del browser e i proxy permissivi mascherano il sintomo su una sola macchina mentre consegnano il guasto a ogni utente. La correzione giusta richiede pochi minuti: configurare il server (o la dashboard della piattaforma) perché consenta le origin che devono chiamarlo.'
  - question: 'Qual è la differenza tra CORS, CSRF e CSP?'
    answer: 'Tre compiti diversi. CORS regola quali origin possono leggere le risposte di un server. CSRF è un attacco – sfruttare i cookie di una persona per forgiare richieste – contrastato da token e cookie SameSite, non da CORS. CSP è la politica propria di una pagina, che limita ciò che può caricare ed eseguire: lo strumento anti-XSS. Acronimi vicini, meccanismi ortogonali.'
codeLanguages: [javascript, dart, swift, kotlin]
externalAuthorities:
  - name: 'CORS — MDN Web Docs'
    url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS'
  - name: 'Fetch Standard — CORS protocol (WHATWG)'
    url: 'https://fetch.spec.whatwg.org/#http-cors-protocol'
  - name: 'Same-origin policy — MDN Web Docs'
    url: 'https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy'
  - name: 'Back4app documentation'
    url: 'https://www.back4app.com/docs'
  - name: 'Cross-origin resource sharing — Wikipedia'
    url: 'https://en.wikipedia.org/wiki/Cross-origin_resource_sharing'
cta:
  title: 'Cross-origin che funziona e basta'
  text: 'Le API di Back4app rispondono ai preflight e inviano gli header CORS corretti dal primo momento – la tua app web chiama il backend da qualunque origin autorizzi, mentre le app native si risparmiano del tutto la cerimonia. Mai più trucchi con i proxy.'
  linkText: 'Inizia gratis'
  linkUrl: 'https://www.back4app.com/signup'
author: 'Back4app Engineering'
publishedDate: '2026-10-09'
translationKey: cors-cross-origin-resource-sharing
---

**CORS è un meccanismo del browser con cui un server dichiara quali altre origin possono chiamarlo, allentando di proposito la same-origin policy.** Due riformulazioni dissolvono quasi tutta la confusione: è il *browser* a imporlo (non il server, ed è per questo che curl funziona), ed è il *server* a correggerlo (non il frontend, ed è per questo che nessuna quantità di JavaScript cambia le cose). Tutto il resto sono header.

## Punti chiave

| Domanda | Risposta |
| --- | --- |
| Il fondamento | Same-Origin Policy: per impostazione predefinita gli script non possono leggere le risposte di altre origin |
| Un'origin | schema + host + porta – tutti e tre devono corrispondere |
| CORS | Header del server che abilitano origin precise; il browser impone |
| Preflight | Un OPTIONS "posso?" prima delle richieste non semplici |
| La verità eterna | Gli errori CORS si correggono sul server, punto |

## Tutto il protocollo, sul filo

```text
# Preflight: il browser chiede prima di un PUT con un header di autenticazione
OPTIONS /classes/Product HTTP/1.1
Origin: https://app.example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: x-parse-session-token

# Il permesso rilasciato dal server
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://app.example.com   ← questa origin può leggere
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: x-parse-session-token
Access-Control-Max-Age: 7200         ← risposta in cache; nessun preflight ripetuto

# Allora, e solo allora, parte la richiesta vera.
```

Come si presenta dal codice applicativo – e la verità di piattaforma che insegnano le schede: CORS è una questione di *browser*, che le app native non incontrano mai:

**JavaScript:**

```javascript
// Browser JavaScript — Back4app JS SDK
// A cross-origin call that just works: the platform answers the
// preflight and sends the CORS headers, so the browser lets it through
Parse.initialize('APP_ID', 'JS_KEY');
Parse.serverURL = 'https://parseapi.back4app.com'; // different origin than your site

const products = await new Parse.Query('Product').find();
// No proxy hacks, no "disable CORS" — the server side is configured correctly.
```

**Flutter:**

```dart
// Flutter / Dart — Back4app Flutter SDK
// Native apps have no same-origin policy — CORS is a browser concern.
// Flutter Web, however, DOES enforce it: same browser rules apply there.
final query = QueryBuilder<ParseObject>(ParseObject('Product'));
final response = await query.query();
// Works identically on mobile and web because the server sends CORS headers.
```

**Swift:**

```swift
// iOS / Swift — Back4app Swift SDK
// No browser, no same-origin policy: CORS never applies to native iOS.
// The same backend serves browsers (with CORS headers) and apps alike.
let query = Product.query()
query.find { result in
  if case .success(let products) = result { render(products) }
}
```

**Kotlin:**

```kotlin
// Android / Kotlin — Back4app Android SDK
// No browser, no same-origin policy: CORS never applies to native Android.
// The same backend serves browsers (with CORS headers) and apps alike.
val query = ParseQuery.getQuery<ParseObject>("Product")
query.findInBackground { products, e ->
  if (e == null) render(products)
}
```

## Il flusso, deciso

```mermaid
flowchart TB
  accTitle: Come un browser decide una richiesta cross-origin
  accDescr: Le richieste di pari origin procedono direttamente; le richieste cross-origin semplici vengono inviate e la loro risposta viene controllata in cerca di un header allow-origin; le richieste non semplici attivano prima un preflight OPTIONS, e qualsiasi header mancante o non corrispondente porta il browser a bloccare la risposta per la pagina.
  R["Uno script invia una richiesta"] --> S{"Stessa origin?"}
  S -- sì --> OK["Procede, senza CORS"]
  S -- no --> T{"Richiesta semplice?<br/>(GET/HEAD/POST, header della safelist)"}
  T -- sì --> D["Invio; controllo della risposta:<br/>Access-Control-Allow-Origin"]
  T -- no --> P["Prima il preflight OPTIONS"]
  P --> D
  D -->|"l'header corrisponde all'origin"| OK2["Risposta leggibile"]
  D -->|"mancante / non corrisponde"| B["Bloccata dal browser<br/>(l'errore in console)"]
```

Due dettagli reggono la maggior parte delle sessioni di debug: una **richiesta semplice** (GET/HEAD/POST con header della safelist e content type basilari) salta il preflight – ed è per questo che aggiungere un header `Authorization` all'improvviso "rompe" un endpoint che funzionava; e le **richieste con credentials** stringono tutto – i cookie circolano solo con `Access-Control-Allow-Credentials: true` *più* un'origin esatta, mai il wildcard, secondo [la specifica](https://fetch.spec.whatwg.org/#http-cors-protocol).

## Come correggere gli errori CORS più comuni (errore → causa → correzione)

| La console dice | Che cosa è successo davvero | Correzione (sempre lato server) |
| --- | --- | --- |
| No 'Access-Control-Allow-Origin' header | Il server non ha mai abilitato quell'origin | Aggiungere la propria origin all'elenco consentito |
| Origin not allowed by Access-Control-Allow-Origin | L'allowlist esiste; quell'origin non c'è | Aggiungere schema+host+porta esatti |
| Response to preflight… doesn't pass | OPTIONS non gestito oppure header incompleti | Rispondere a OPTIONS con metodi/header |
| Wildcard '*' cannot be used with credentials | Cookie + `*` – combinazione vietata | Elencare le origin in modo esplicito |
| Request header not allowed | Header personalizzato assente dall'allowlist | Aggiungerlo ad Access-Control-Allow-Headers |

E l'anti-correzione che vale la pena nominare: disattivare CORS con un flag del browser o passare da proxy di sviluppo permissivi rende l'errore invisibile *solo su una macchina* – il deployment resta rotto per gli utenti. La correzione vera è una configurazione del server che si misura in minuti.

## Casi d'uso tipici

- **SPA + API su origin diverse** – app.example.com che chiama api.example.com: il caso quotidiano per cui CORS esiste.
- **Sviluppo locale** – localhost:3000 contro un backend reale; conviene consentire l'origin di sviluppo, non disattivare lo scudo.
- **API pubbliche** – origin wildcard, senza credentials: corretto e sicuro per dati davvero pubblici.
- **Piattaforme multi-frontend** – più app, un solo backend, un elenco esplicito di origin per ambiente.
- **Backend BaaS** – la piattaforma risponde ai preflight e invia gli header; resta soltanto da dichiarare le origin consentite.

## Wildcard vs. origin esplicite: matrice decisionale

| Configurazione | Giusta quando… | Mai quando… |
| --- | --- | --- |
| Wildcard `*` | API pubblica, senza credentials | Esistono cookie o sessioni utente |
| Elenco esplicito di origin | API private, app con credentials | – (è questa la risposta predefinita) |
| Riflettere l'origin della richiesta | Quasi mai | In combinazione con i credentials – la falla classica |
| Elenchi per ambiente | Igiene fra sviluppo, staging e produzione | La produzione eredita le voci localhost dello sviluppo |

Una riformulazione di sicurezza chiude la matrice: CORS **non è controllo degli accessi** – le app native e i server lo ignorano del tutto, quindi protegge gli *utenti del browser* dai siti malevoli, non l'API da chi la chiama. Quel lavoro lo fanno l'autenticazione e i [permessi al livello dei dati](/glossary/it/sicurezza-dati-vs-applicazione/); CORS decide soltanto quali script di quali siti possono leggere le risposte.

## Limiti e trade-off

- **Governa soltanto i browser.** Tutto ciò che non è un browser gli passa davanti – un elenco di origin non va mai confuso con un'autorizzazione.
- **I preflight costano un round trip** sulle richieste non semplici; la messa in cache via `Access-Control-Max-Age` è la correzione a basso costo che tutti dimenticano.
- **Una configurazione sbagliata fallisce chiusa e in modo rumoroso** – bene per la sicurezza, brutale per il debug senza la tabella errore→correzione qui sopra.
- **Gli elenchi di origin sono stato dell'ambiente.** Le origin di staging si infilano nelle configurazioni di produzione; l'elenco va verificato come qualsiasi credenziale.
- **CORS ≠ CSRF ≠ CSP.** Acronimi vicini, difese distinte – i cookie hanno comunque bisogno di protezione SameSite o a token, e le pagine di una content policy, mentre CORS gestisce soltanto la lettura cross-origin.

## CORS su Back4app

Back4app è una piattaforma open-source di Backend as a Service (BaaS) che combina database gestito, API REST e GraphQL generate automaticamente, autenticazione, archiviazione di file e funzioni serverless con Cloud Code. La scocciatura CORS arriva già risolta: le API della piattaforma rispondono ai preflight e inviano gli header corretti, così le app nel browser chiamano il backend dalle origin consentite senza trucchi con i proxy – la scheda JavaScript qui sopra è tutta l'esperienza – mentre le schede Flutter, Swift e Kotlin dimostrano la verità più discreta: i client nativi non incontrano mai la cerimonia. La sicurezza vera resta dove deve stare: sessioni, ACL e permessi di classe applicati lato server a ogni richiesta, da qualunque origin.
