Immaginiamo di aver realizzato una Web API e di volerne agevolare l'uso su applicazioni web sviluppate da terze parti.
Ben presto, potremmo ricevere delle segnalazioni sul fatto che le richieste Ajax alla nostra Web API falliscono, perché bloccate dal browser con un errore simile al seguente:
XMLHttpRequest cannot load 'nostrodominio.com' No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'dominiodiorigine.com' is therefore not allowed access.
Ciò succede perché il browser sta mettendo in atto la same origin policy (https://www.w3.org/Security/wiki/Same_Origin_Policy), una restrizione che impedisce ad una pagina web di inviare richieste Ajax cross-origin, ovvero a contenuti pubblicati su altri domini, porte o protocolli.
Fortunatamente, i browser moderni adottano un meccanismo denominato CORS - acronimo di Cross-origin resource sharing - che restituisce a noi sviluppatori la facoltà di decidere se tali richieste vanno accolte o bloccate. Nel momento in cui la pagina vorrebbe eseguire una richiesta Ajax, il browser invierà subito una richiesta preflight al nostro server e prenderà una decisione in accordo con le nostre disposizioni.
Per supportare CORS non è necessario comprenderne a fondo tutte le sfumature, perché possiamo avvalerci del pacchetto Microsoft.AspNet.WebApi.Cors, liberamente scaricabile da NuGet. Avviamo l'installazione lanciando il seguente comando dalla console di gestione pacchetti di Visual Studio:
Install-Package Microsoft.AspNet.WebApi.Cors
Poi apriamo il file App_Start/WebApiConfig.cs del nostro progetto ASP.NET Web API ed inseriamo questa riga nel metodo Register:
config.EnableCors();
Ora non ci resta che usare la classe EnableCorsAttribute, che dispone di un costruttore con tre parametri di configurazione:
- origins, è una stringa contenente i nomi a dominio (separati da virgola) da cui vogliamo accettare richieste. Usiamo il carattere * se vogliamo accettare richieste da qualsiasi altro dominio;
- headers, è una stringa contenente i nomi di intestazioni HTTP personalizzate che il client può aggiungere alla sua richiesta. Usiamo il carattere * per dargli completa libertà in tal senso;
- methods, è una stringa contenente i metodi HTTP supportati. In una Web API di tipo REST, abiliteremo solo il metodo "GET" se vogliamo consentire la sola lettura, oppure "GET,POST,PUT,DELETE" per abilitare anche le tipiche operazioni di scrittura. Usiamo il carattere * se invece preferiamo non porre alcuna restrizione.
Ci è consentito usare l'EnableCorsAttribute in vari modi. Ad esempio possiamo usarlo in maniera opt-in, sulla singola action:
[EnableCors(origins: "*", headers: "*", methods: "GET")] public IEnumerable<Temperatura> GetTemperature(){ //omissis }
Oppure sul singolo controller, in modo da coinvolgere tutte le sue actions.
[EnableCors(origins: "*", headers: "*", methods: "GET,POST")] public class TemperatureController : ApiController { //omissis }
Infine, possiamo usarlo a livello globale. In questo caso torniamo nel file App_Start/WebApiConfig.cs ed aggiorniamo la riga aggiunta in precedenza al metodo Register:
config.EnableCors(new EnableCorsAttribute(origins: "*", headers: "*", methods: "GET,POST,PUT,DELETE"));
In quest'ultimo caso avremo supportato CORS su ogni action della nostra Web API. Se volessimo escluderne qualcuna, usiamo l'attributo DisableCors per farne l'opt-out.
[DisableCors] public void DeleteTemperatura(int IdTemperatura){ //omissis }
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Change tracking e composition in Entity Framework
Utilizzare Tailwind CSS all'interno di React: installazione
Persistere la ChatHistory di Semantic Kernel in ASP.NET Core Web API per GPT
Migrare una service connection a workload identity federation in Azure DevOps
Hosting di componenti WebAssembly in un'applicazione Blazor static
Ottimizzare le performance delle collection con le classi FrozenSet e FrozenDictionary
Come migrare da una form non tipizzata a una form tipizzata in Angular
C# 12: Cosa c'è di nuovo e interessante
Ottimizzare la latenza in Blazor 8 tramite InteractiveAuto render mode
Utilizzare i primary constructor di C# per inizializzare le proprietà
Eseguire query manipolando liste di tipi semplici con Entity Framework Core