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
Evitare (o ridurre) il repo-jacking sulle GitHub Actions
Eseguire query per recuperare il padre di un record che sfrutta il tipo HierarchyID in Entity Framework
Sfruttare GPT-4o realtime su Azure Open AI per conversazioni vocali
Configurare il nome della run di un workflow di GitHub in base al contesto di esecuzione
Referenziare un @layer più alto in CSS
Garantire la provenienza e l'integrità degli artefatti prodotti su GitHub
Effettuare il binding di date in Blazor
Generare HTML a runtime a partire da un componente Razor in ASP.NET Core
Supportare la sessione affinity di Azure App Service con Application Gateway
Evitare il flickering dei componenti nel prerender di Blazor 8
Eseguire un metodo asincrono dopo il set di una proprietà in Blazor 8
Persistere la ChatHistory di Semantic Kernel in ASP.NET Core Web API per GPT