Attivare richieste multiorigine nell'API Web ASP.NET 2Enable cross-origin requests in ASP.NET Web API 2

da Mike Wassonby Mike Wasson

Protezione del browser impedisce a una pagina web da creare richieste AJAX a un altro dominio.Browser security prevents a web page from making AJAX requests to another domain. Questa restrizione viene chiamata il criterio della stessa originee impedisce a un sito dannoso di leggere dati sensibili da un altro sito.This restriction is called the same-origin policy, and prevents a malicious site from reading sensitive data from another site. Tuttavia, in alcuni casi si potrebbe voler consentire ad altri siti di chiamare l'API web.However, sometimes you might want to let other sites call your web API.

Cross Origin Resource Sharing (le origini CORS) è uno standard W3C che consente a un server di ridurre i criteri di corrispondenza dell'origine.Cross Origin Resource Sharing (CORS) is a W3C standard that allows a server to relax the same-origin policy. Con CORS un server può consentire in modo esplicito alcune richieste multiorigine e rifiutarne altre.Using CORS, a server can explicitly allow some cross-origin requests while rejecting others. CORS è più sicuri e flessibili rispetto a tecniche precedenti, ad esempio JSONP.CORS is safer and more flexible than earlier techniques such as JSONP. Questa esercitazione illustra come abilitare CORS nell'applicazione API Web.This tutorial shows how to enable CORS in your Web API application.

Software utilizzato nell'esercitazioneSoftware used in the tutorial

IntroduzioneIntroduction

Questa esercitazione illustra che il supporto di CORS nell'API Web ASP.NET.This tutorial demonstrates CORS support in ASP.NET Web API. Si inizierà creando due progetti ASP.NET – uno chiamato "servizio Web", che ospita un controller API Web, e l'altro denominato "WebClient", che chiama WebService.We'll start by creating two ASP.NET projects – one called "WebService", which hosts a Web API controller, and the other called "WebClient", which calls WebService. Poiché le due applicazioni sono ospitate in domini diversi, una richiesta AJAX da WebClient per servizio Web è una richiesta multiorigine.Because the two applications are hosted at different domains, an AJAX request from WebClient to WebService is a cross-origin request.

Che cos'è "origin stesso"?What is "same origin"?

Due URL abbia la stessa origine se dispongono di porte, host e gli schemi identici.Two URLs have the same origin if they have identical schemes, hosts, and ports. (RFC 6454)(RFC 6454)

Questi due URL abbia la stessa origine:These two URLs have the same origin:

  • http://example.com/foo.html
  • http://example.com/bar.html

Questi URL sono le entità Origin diversa rispetto al precedente due:These URLs have different origins than the previous two:

  • http://example.net -Altro dominiohttp://example.net - Different domain
  • http://example.com:9000/foo.html -Porta diversahttp://example.com:9000/foo.html - Different port
  • https://example.com/foo.html -Schema differentehttps://example.com/foo.html - Different scheme
  • http://www.example.com/foo.html -Sottodominio diversohttp://www.example.com/foo.html - Different subdomain

Note

Internet Explorer non considera la porta quando si confrontano le entità Origin.Internet Explorer does not consider the port when comparing origins.

Creare il progetto servizio WebCreate the WebService project

Note

In questa sezione presuppone che si conosca già come creare progetti API Web.This section assumes you already know how to create Web API projects. In caso contrario, vedere Introduzione all'API Web ASP.NET.If not, see Getting Started with ASP.NET Web API.

  1. Avviare Visual Studio e creare una nuova applicazione Web ASP.NET (.NET Framework) progetto.Start Visual Studio and create a new ASP.NET Web Application (.NET Framework) project.

  2. Nel nuova applicazione Web ASP.NET finestra di dialogo, seleziona la vuota modello di progetto.In the New ASP.NET Web Application dialog box, select the Empty project template. Sotto aggiungere le cartelle e riferimenti per di base, selezionare la API Web casella di controllo.Under Add folders and core references for, select the Web API checkbox.

    Finestra Nuovo progetto ASP.NET in Visual Studio

  3. Aggiungere un controller API Web denominato TestController con il codice seguente:Add a Web API controller named TestController with the following code:

    using System.Net.Http;
    using System.Web.Http;
    
    namespace WebService.Controllers
    {
        public class TestController : ApiController
        {
            public HttpResponseMessage Get()
            {
                return new HttpResponseMessage()
                {
                    Content = new StringContent("GET: Test message")
                };
            }
    
            public HttpResponseMessage Post()
            {
                return new HttpResponseMessage()
                {
                    Content = new StringContent("POST: Test message")
                };
            }
    
            public HttpResponseMessage Put()
            {
                return new HttpResponseMessage()
                {
                    Content = new StringContent("PUT: Test message")
                };
            }
        }
    }
    
  4. È possibile eseguire l'applicazione in locale o distribuirla in Azure.You can run the application locally or deploy to Azure. (Per le schermate contenute in questa esercitazione, distribuire l'app per App Web di servizio App di Azure.) Per verificare che l'API web è operativa, passare a http://hostname/api/test/, dove hostname è il dominio in cui è distribuita l'applicazione.(For the screenshots in this tutorial, the app deploys to Azure App Service Web Apps.) To verify that the web API is working, navigate to http://hostname/api/test/, where hostname is the domain where you deployed the application. Si dovrebbe vedere il testo di risposta, "ottenere: Messaggio di prova".You should see the response text, "GET: Test Message".

    Messaggio di prova di Web browser che mostra

Creare il progetto WebClientCreate the WebClient project

  1. Creare un'altra applicazione Web ASP.NET (.NET Framework) del progetto e selezionare il MVC modello di progetto.Create another ASP.NET Web Application (.NET Framework) project and select the MVC project template. Facoltativamente, selezionare Modifica autenticazione > Nessuna autenticazione.Optionally, select Change Authentication > No Authentication. L'autenticazione non è necessario per questa esercitazione.You don't need authentication for this tutorial.

    Modello MVC nella finestra di dialogo Nuovo progetto ASP.NET in Visual Studio

  2. Nelle Esplora soluzioni, aprire il file Views/Home/Index.cshtml.In Solution Explorer, open the file Views/Home/Index.cshtml. Sostituire il codice in questo file con il codice seguente:Replace the code in this file with the following:

    <div>
        <select id="method">
            <option value="get">GET</option>
            <option value="post">POST</option>
            <option value="put">PUT</option>
        </select>
        <input type="button" value="Try it" onclick="sendRequest()" />
        <span id='value1'>(Result)</span>
    </div>
    
    @section scripts {
    <script>
        // TODO: Replace with the URL of your WebService app
        var serviceUrl = 'http://mywebservice/api/test'; 
    
        function sendRequest() {
            var method = $('#method').val();
    
            $.ajax({
                type: method,
                url: serviceUrl
            }).done(function (data) {
                $('#value1').text(data);
            }).fail(function (jqXHR, textStatus, errorThrown) {
                $('#value1').text(jqXHR.responseText || textStatus);
            });
        }
    </script>
    }
    

    Per il serviceUrl variabile, usare l'URI del servizio Web app.For the serviceUrl variable, use the URI of the WebService app.

  3. Eseguire localmente l'app WebClient o pubblicarla in un altro sito Web.Run the WebClient app locally or publish it to another website.

Quando si sceglie il pulsante "prova", viene inviata una richiesta AJAX per l'app di servizio Web utilizzando il metodo HTTP elencato nella casella a discesa (GET, POST o PUT).When you click the "Try It" button, an AJAX request is submitted to the WebService app using the HTTP method listed in the dropdown box (GET, POST, or PUT). Ciò consente di esaminare le diverse richieste multiorigine.This lets you examine different cross-origin requests. Attualmente, l'app del servizio Web non supportano CORS, in modo che se si fa clic sul pulsante, si otterrà un errore.Currently, the WebService app does not support CORS, so if you click the button you'll get an error.

"Prova" errore nel browser

Note

Se si osserva il traffico HTTP in uno strumento, ad esempio Fiddler, si noterà che il browser invia la richiesta GET e la richiesta ha esito positivo, ma la chiamata AJAX restituisce un errore.If you watch the HTTP traffic in a tool like Fiddler, you'll see that the browser does send the GET request, and the request succeeds, but the AJAX call returns an error. È importante comprendere che Criteri di corrispondenza dell'origine non impediscano il browser dal invio la richiesta.It's important to understand that same-origin policy does not prevent the browser from sending the request. Al contrario, impedisce all'applicazione di visualizzare il risposta.Instead, it prevents the application from seeing the response.

Debugger web Fiddler che mostra le richieste web

Abilitare CORSEnable CORS

A questo punto è possibile abilitare CORS nell'app di servizio Web.Now let's enable CORS in the WebService app. In primo luogo, aggiungere il pacchetto NuGet di CORS.First, add the CORS NuGet package. In Visual Studio dal degli strumenti dal menu Gestione pacchetti NuGet, quindi selezionare Package Manager Console.In Visual Studio, from the Tools menu, select NuGet Package Manager, then select Package Manager Console. Nella finestra della Console di gestione pacchetti, digitare il comando seguente:In the Package Manager Console window, type the following command:

Install-Package Microsoft.AspNet.WebApi.Cors

Questo comando installa il pacchetto più recente e aggiorna tutte le dipendenze, incluse le librerie di API Web di base.This command installs the latest package and updates all dependencies, including the core Web API libraries. Usare il -Version flag a una versione specifica.Use the -Version flag to target a specific version. Il pacchetto CORS richiede Web API 2.0 o versione successiva.The CORS package requires Web API 2.0 or later.

Aprire il file App_Start/WebApiConfig.cs.Open the file App_Start/WebApiConfig.cs. Aggiungere il codice seguente per il webapiconfig. Register metodo:Add the following code to the WebApiConfig.Register method:

using System.Web.Http;
namespace WebService
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // New code
            config.EnableCors();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
}

Successivamente, aggiungere il [EnableCors] dell'attributo di TestController classe:Next, add the [EnableCors] attribute to the TestController class:

using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Cors;

namespace WebService.Controllers
{
    [EnableCors(origins: "http://mywebclient.azurewebsites.net", headers: "*", methods: "*")]
    public class TestController : ApiController
    {
        // Controller methods not shown...
    }
}

Per il le entità Origin parametro, usare l'URI in cui è distribuita l'applicazione WebClient.For the origins parameter, use the URI where you deployed the WebClient application. In questo modo le richieste multiorigine da WebClient, mentre comunque impedire tutte le altre richieste tra domini.This allows cross-origin requests from WebClient, while still disallowing all other cross-domain requests. In un secondo momento, descriverò i parametri per [EnableCors] in modo più dettagliato.Later, I'll describe the parameters for [EnableCors] in more detail.

Non includere una barra rovesciata alla fine del le entità Origin URL.Do not include a forward slash at the end of the origins URL.

Ridistribuire l'applicazione di servizio Web aggiornato.Redeploy the updated WebService application. Non devi aggiornare WebClient.You don't need to update WebClient. A questo punto la richiesta AJAX da WebClient avrà esito positivo.Now the AJAX request from WebClient should succeed. Sono consentiti tutti i metodi GET, PUT e POST.The GET, PUT, and POST methods are all allowed.

Messaggio di test riuscito di Web browser che mostra

Funzionamento della condivisione CORSHow CORS Works

In questa sezione viene descritto cosa succede in una richiesta CORS, il livello dei messaggi HTTP.This section describes what happens in a CORS request, at the level of the HTTP messages. È importante comprendere il funzionamento di CORS, in modo che sia possibile configurare il [EnableCors] attributo correttamente e risolvere i problemi se ciò non funziona come previsto.It's important to understand how CORS works, so that you can configure the [EnableCors] attribute correctly and troubleshoot if things don't work as you expect.

La specifica CORS introduce diverse nuove intestazioni HTTP che attivare richieste multiorigine.The CORS specification introduces several new HTTP headers that enable cross-origin requests. Se un browser supporta la condivisione CORS, imposta le intestazioni automaticamente per le richieste multiorigine. non è necessario eseguire alcuna operazione speciale nel codice JavaScript.If a browser supports CORS, it sets these headers automatically for cross-origin requests; you don't need to do anything special in your JavaScript code.

Di seguito è riportato un esempio di una richiesta multiorigine.Here is an example of a cross-origin request. L'intestazione "Origin" offre il dominio del sito che effettua la richiesta.The "Origin" header gives the domain of the site that is making the request.

GET http://myservice.azurewebsites.net/api/test HTTP/1.1
Referer: http://myclient.azurewebsites.net/
Accept: */*
Accept-Language: en-US
Origin: http://myclient.azurewebsites.net
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)
Host: myservice.azurewebsites.net

Se il server consente la richiesta, imposta l'intestazione Access-Control-Allow-Origin.If the server allows the request, it sets the Access-Control-Allow-Origin header. Il valore di questa intestazione corrisponde all'intestazione di origine o è il valore del carattere jolly "*", che significa che è consentita qualsiasi origine.The value of this header either matches the Origin header, or is the wildcard value "*", meaning that any origin is allowed.

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/plain; charset=utf-8
Access-Control-Allow-Origin: http://myclient.azurewebsites.net
Date: Wed, 05 Jun 2013 06:27:30 GMT
Content-Length: 17

GET: Test message

Se la risposta non include l'intestazione Access-Control-Allow-Origin, la richiesta AJAX non riesce.If the response does not include the Access-Control-Allow-Origin header, the AJAX request fails. In particolare, il browser non consente la richiesta.Specifically, the browser disallows the request. Anche se il server restituisce una risposta con esito positivo, il browser non rende la risposta disponibili per l'applicazione client.Even if the server returns a successful response, the browser does not make the response available to the client application.

Richieste preliminariPreflight Requests

Per alcune richieste CORS, il browser invia una richiesta aggiuntiva, definita "richiesta preliminare," prima dell'invio della richiesta effettiva per la risorsa.For some CORS requests, the browser sends an additional request, called a "preflight request", before it sends the actual request for the resource.

Il browser può ignorare la richiesta preliminare se vengono soddisfatte le condizioni seguenti:The browser can skip the preflight request if the following conditions are true:

  • Il metodo di richiesta è GET, HEAD o POST, eThe request method is GET, HEAD, or POST, and

  • L'applicazione non imposta le intestazioni di richiesta diversa da Accept, Accept-Language, Content-Language, Content-Type o Last-eventi-ID, eThe application does not set any request headers other than Accept, Accept-Language, Content-Language, Content-Type, or Last-Event-ID, and

  • L'intestazione Content-Type (se impostato) è uno dei seguenti:The Content-Type header (if set) is one of the following:

    • application/x-www-form-urlencodedapplication/x-www-form-urlencoded
    • multipart/form-datamultipart/form-data
    • text/plaintext/plain

Si applica la regola sulle intestazioni di richiesta alle intestazioni che l'applicazione imposta chiamando setRequestHeader nel XMLHttpRequest oggetto.The rule about request headers applies to headers that the application sets by calling setRequestHeader on the XMLHttpRequest object. (Specifica CORS chiama questi "intestazioni di richiesta autore"). La regola non si applica alle intestazioni il browser impostare, ad esempio User-Agent, Host o Content-Length.(The CORS specification calls these "author request headers".) The rule does not apply to headers the browser can set, such as User-Agent, Host, or Content-Length.

Di seguito è riportato un esempio di una richiesta preliminare:Here is an example of a preflight request:

OPTIONS http://myservice.azurewebsites.net/api/test HTTP/1.1
Accept: */*
Origin: http://myclient.azurewebsites.net
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: accept, x-my-custom-header
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)
Host: myservice.azurewebsites.net
Content-Length: 0

La richiesta preliminare viene utilizzato il metodo OPTIONS HTTP.The pre-flight request uses the HTTP OPTIONS method. Include due intestazioni speciali:It includes two special headers:

  • Access-Control-Request-Method: Il metodo HTTP che verrà usato per la richiesta effettiva.Access-Control-Request-Method: The HTTP method that will be used for the actual request.
  • Access-Control-Request-Headers: Un elenco di intestazioni di richiesta che il applicazione impostare per la richiesta effettiva.Access-Control-Request-Headers: A list of request headers that the application set on the actual request. (Anche in questo caso, ciò non includono le intestazioni che imposta il browser.)(Again, this does not include headers that the browser sets.)

Ecco un esempio di risposta, presupponendo che il server consente la richiesta:Here is an example response, assuming that the server allows the request:

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 0
Access-Control-Allow-Origin: http://myclient.azurewebsites.net
Access-Control-Allow-Headers: x-my-custom-header
Access-Control-Allow-Methods: PUT
Date: Wed, 05 Jun 2013 06:33:22 GMT

La risposta include un'intestazione Access-Control-Allow-Methods in cui sono elencati i metodi consentiti e, facoltativamente, un'intestazione Access-Control-Consenti-Headers, che elenca le intestazioni consentite.The response includes an Access-Control-Allow-Methods header that lists the allowed methods, and optionally an Access-Control-Allow-Headers header, which lists the allowed headers. Se la richiesta preliminare ha esito positivo, il browser invia la richiesta effettiva, come descritto in precedenza.If the preflight request succeeds, the browser sends the actual request, as described earlier.

Strumenti usati comunemente per testare gli endpoint con le richieste preliminari opzioni (ad esempio, Fiddler e Postman) non inviare le intestazioni di opzioni obbligatorie per impostazione predefinita.Tools commonly used to test endpoints with preflight OPTIONS requests (for example, Fiddler and Postman) don't send the required OPTIONS headers by default. Verificare che il Access-Control-Request-Method e Access-Control-Request-Headers intestazioni vengono inviate con la richiesta e intestazioni di opzioni di raggiungere l'app tramite IIS.Confirm that the Access-Control-Request-Method and Access-Control-Request-Headers headers are sent with the request and that OPTIONS headers reach the app through IIS.

Per configurare IIS per consentire a un'app ASP.NET ricevere e gestire le richieste di opzione, aggiungere la seguente configurazione dell'app Web. config del file nei <system.webServer><handlers> sezione:To configure IIS to allow an ASP.NET app to receive and handle OPTION requests, add the following configuration to the app's web.config file in the <system.webServer><handlers> section:

<system.webServer>
  <handlers>
    <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
    <remove name="OPTIONSVerbHandler" />
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
  </handlers>
</system.webServer>

La rimozione di OPTIONSVerbHandler impedisce a IIS di gestione delle richieste di opzioni.The removal of OPTIONSVerbHandler prevents IIS from handling OPTIONS requests. La sostituzione di ExtensionlessUrlHandler-Integrated-4.0 consente le richieste di opzioni raggiungere l'app perché la registrazione del modulo predefinito consente solo le richieste GET, HEAD, POST e DEBUG con gli URL senza estensione.The replacement of ExtensionlessUrlHandler-Integrated-4.0 allows OPTIONS requests to reach the app because the default module registration only allows GET, HEAD, POST, and DEBUG requests with extensionless URLs.

Regole di ambito per [EnableCors]Scope Rules for [EnableCors]

È possibile abilitare CORS per ogni azione, per ogni controller o a livello globale per tutti i controller API Web nell'applicazione.You can enable CORS per action, per controller, or globally for all Web API controllers in your application.

Per ogni azionePer Action

Per abilitare CORS per una singola azione, impostare il [EnableCors] attributo del metodo di azione.To enable CORS for a single action, set the [EnableCors] attribute on the action method. L'esempio seguente Abilita CORS per il GetItem solo metodo.The following example enables CORS for the GetItem method only.

public class ItemsController : ApiController
{
    public HttpResponseMessage GetAll() { ... }

    [EnableCors(origins: "http://www.example.com", headers: "*", methods: "*")]
    public HttpResponseMessage GetItem(int id) { ... }

    public HttpResponseMessage Post() { ... }
    public HttpResponseMessage PutItem(int id) { ... }
}

Per ogni ControllerPer Controller

Se si imposta [EnableCors] nella classe controller, si applica a tutte le azioni nel controller.If you set [EnableCors] on the controller class, it applies to all the actions on the controller. Per disabilitare CORS per un'azione, aggiungere il [DisableCors] attributo all'azione.To disable CORS for an action, add the [DisableCors] attribute to the action. L'esempio seguente Abilita CORS per qualsiasi metodo ad eccezione PutItem.The following example enables CORS for every method except PutItem.

[EnableCors(origins: "http://www.example.com", headers: "*", methods: "*")]
public class ItemsController : ApiController
{
    public HttpResponseMessage GetAll() { ... }
    public HttpResponseMessage GetItem(int id) { ... }
    public HttpResponseMessage Post() { ... }

    [DisableCors]
    public HttpResponseMessage PutItem(int id) { ... }
}

A livello globaleGlobally

Per abilitare CORS per tutti i controller API Web nell'applicazione, passare un EnableCorsAttribute dell'istanza per il EnableCors metodo:To enable CORS for all Web API controllers in your application, pass an EnableCorsAttribute instance to the EnableCors method:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        var cors = new EnableCorsAttribute("www.example.com", "*", "*");
        config.EnableCors(cors);
        // ...
    }
}

Se si imposta l'attributo più di un ambito, l'ordine di precedenza è:If you set the attribute at more than one scope, the order of precedence is:

  1. OperazioneAction
  2. ControllerController
  3. GlobalGlobal

Impostare le origini consentiteSet the allowed origins

Il le entità Origin parametro delle [EnableCors] attributo specifica quali origini sono consentite per accedere alla risorsa.The origins parameter of the [EnableCors] attribute specifies which origins are allowed to access the resource. Il valore è un elenco delimitato da virgole di origini consentite.The value is a comma-separated list of the allowed origins.

[EnableCors(origins: "http://www.contoso.com,http://www.example.com", 
    headers: "*", methods: "*")]

È anche possibile usare il valore del carattere jolly "*" per consentire le richieste da tutte le entità Origin.You can also use the wildcard value "*" to allow requests from any origins.

Si consideri con attenzione prima di consentire le richieste provenienti da qualsiasi origine.Consider carefully before allowing requests from any origin. Significa che letteralmente qualsiasi sito Web può eseguire chiamate AJAX all'API Web.It means that literally any website can make AJAX calls to your web API.

// Allow CORS for all origins. (Caution!)
[EnableCors(origins: "*", headers: "*", methods: "*")]

Impostare i metodi HTTP consentitiSet the allowed HTTP methods

Il metodi parametro delle [EnableCors] attributo specifica quali metodi HTTP consentiti per accedere alla risorsa.The methods parameter of the [EnableCors] attribute specifies which HTTP methods are allowed to access the resource. Per consentire tutti i metodi, usare il valore del carattere jolly "*".To allow all methods, use the wildcard value "*". Nell'esempio seguente consente solo le richieste GET e POST.The following example allows only GET and POST requests.

[EnableCors(origins: "http://www.example.com", headers: "*", methods: "get,post")]
public class TestController : ApiController
{
    public HttpResponseMessage Get() { ... }
    public HttpResponseMessage Post() { ... }
    public HttpResponseMessage Put() { ... }    
}

Impostare le intestazioni di richieste consentiteSet the allowed request headers

Questo articolo ha illustrato in precedenza come una richiesta preliminare può includere un'intestazione Access-Control-Request-Headers, elenca le intestazioni HTTP impostate dall'applicazione (la cosiddetta "creare le intestazioni delle richieste").This article described earlier how a preflight request might include an Access-Control-Request-Headers header, listing the HTTP headers set by the application (the so-called "author request headers"). Il intestazioni parametro delle [EnableCors] attributo specifica quali intestazioni di richiesta di autore sono consentite.The headers parameter of the [EnableCors] attribute specifies which author request headers are allowed. Per consentire tutte le intestazioni, impostare intestazioni a "*".To allow any headers, set headers to "*". A elenco elementi consentiti intestazioni specifiche, impostare intestazioni a un elenco delimitato da virgole delle intestazioni consentite:To whitelist specific headers, set headers to a comma-separated list of the allowed headers:

[EnableCors(origins: "http://example.com", 
    headers: "accept,content-type,origin,x-my-header", methods: "*")]

Tuttavia, i browser non sono completamente coerenti nel modo in cui siano impostate Access-Control-Request-Headers.However, browsers are not entirely consistent in how they set Access-Control-Request-Headers. Ad esempio Chrome include attualmente "origin".For example, Chrome currently includes "origin". FireFox non include le intestazioni standard, ad esempio "Accept", anche quando l'applicazione vengono impostati nello script.FireFox does not include standard headers such as "Accept", even when the application sets them in script.

Se si imposta intestazioni su un valore qualsiasi diverso da "*", è necessario includere almeno "accept", "content-type" e "origin", oltre a eventuali intestazioni personalizzate che si desidera supportare.If you set headers to anything other than "*", you should include at least "accept", "content-type", and "origin", plus any custom headers that you want to support.

Impostare le intestazioni di risposta consentiteSet the allowed response headers

Per impostazione predefinita, il browser non espone tutte le intestazioni di risposta all'applicazione.By default, the browser does not expose all of the response headers to the application. Le intestazioni di risposta che sono disponibili per impostazione predefinita sono:The response headers that are available by default are:

  • Cache-ControlCache-Control
  • Content-LanguageContent-Language
  • Content-TypeContent-Type
  • Alla scadenzaExpires
  • Ultima modificaLast-Modified
  • PragmaPragma

La specifica CORS chiama questi intestazioni di risposta semplice.The CORS spec calls these simple response headers. Per rendere altre intestazioni disponibili per l'applicazione, impostare il exposedHeaders del parametro [EnableCors].To make other headers available to the application, set the exposedHeaders parameter of [EnableCors].

Nell'esempio seguente, il controller Get metodo imposta un'intestazione personalizzata denominata "X-Custom-Header".In the following example, the controller's Get method sets a custom header named ‘X-Custom-Header'. Per impostazione predefinita, il browser non espone questa intestazione in una richiesta multiorigine.By default, the browser will not expose this header in a cross-origin request. Per rendere disponibile l'intestazione, includere "X-Custom-Header" nella exposedHeaders.To make the header available, include ‘X-Custom-Header' in exposedHeaders.

[EnableCors(origins: "*", headers: "*", methods: "*", exposedHeaders: "X-Custom-Header")]
public class TestController : ApiController
{
    public HttpResponseMessage Get()
    {
        var resp = new HttpResponseMessage()
        {
            Content = new StringContent("GET: Test message")
        };
        resp.Headers.Add("X-Custom-Header", "hello");
        return resp;
    }
}

Passare le credenziali in richieste multioriginePass credentials in cross-origin requests

Credenziali richiedono una gestione speciale in una richiesta CORS.Credentials require special handling in a CORS request. Per impostazione predefinita, il browser invia credenziali con una richiesta multiorigine.By default, the browser does not send any credentials with a cross-origin request. Le credenziali includono i cookie, nonché gli schemi di autenticazione HTTP.Credentials include cookies as well as HTTP authentication schemes. Per inviare le credenziali con una richiesta multiorigine, il client deve impostare XMLHttpRequest.withCredentials su true.To send credentials with a cross-origin request, the client must set XMLHttpRequest.withCredentials to true.

Usando XMLHttpRequest direttamente:Using XMLHttpRequest directly:

var xhr = new XMLHttpRequest();
xhr.open('get', 'http://www.example.com/api/test');
xhr.withCredentials = true;

In jQuery:In jQuery:

$.ajax({
    type: 'get',
    url: 'http://www.example.com/api/test',
    xhrFields: {
        withCredentials: true
    }

Inoltre, il server deve consentire le credenziali.In addition, the server must allow the credentials. Per consentire le credenziali multiorigine nell'API Web, impostare il SupportsCredentials proprietà su true nella [EnableCors] attributo:To allow cross-origin credentials in Web API, set the SupportsCredentials property to true on the [EnableCors] attribute:

[EnableCors(origins: "http://myclient.azurewebsites.net", headers: "*", 
    methods: "*", SupportsCredentials = true)]

Se questa proprietà è true, la risposta HTTP includerà un'intestazione di accesso-controllo-Allow-Credentials.If this property is true, the HTTP response will include an Access-Control-Allow-Credentials header. Questa intestazione indica al browser che il server consenta le credenziali per una richiesta multiorigine.This header tells the browser that the server allows credentials for a cross-origin request.

Se il browser invia le credenziali, ma la risposta non include un'intestazione di accesso-controllo-Allow-Credentials valida, il browser non espone la risposta all'applicazione e la richiesta AJAX non riesce.If the browser sends credentials, but the response does not include a valid Access-Control-Allow-Credentials header, the browser will not expose the response to the application, and the AJAX request fails.

Prestare particolare attenzione impostazione SupportsCredentials su true, perché significa che un sito Web all'indirizzo di un altro dominio può inviare le credenziali dell'utente ha eseguito l'accesso all'API Web per conto dell'utente, senza che l'utente ne sia consapevole.Be careful about setting SupportsCredentials to true, because it means a website at another domain can send a logged-in user's credentials to your Web API on the user's behalf, without the user being aware. La specifica CORS inoltre stabilito che l'impostazione le entità Origin al " * " non è valido se SupportsCredentials è true.The CORS spec also states that setting origins to "*" is invalid if SupportsCredentials is true.

Provider criteri CORS personalizzatiCustom CORS policy providers

Il [EnableCors] attributo implementa le ICorsPolicyProvider interfaccia.The [EnableCors] attribute implements the ICorsPolicyProvider interface. È possibile fornire un'implementazione personalizzata creando una classe che deriva da attributo e implementa ICorsPolicyProvider.You can provide your own implementation by creating a class that derives from Attribute and implements ICorsPolicyProvider.

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)]
public class MyCorsPolicyAttribute : Attribute, ICorsPolicyProvider 
{
    private CorsPolicy _policy;

    public MyCorsPolicyAttribute()
    {
        // Create a CORS policy.
        _policy = new CorsPolicy
        {
            AllowAnyMethod = true,
            AllowAnyHeader = true
        };

        // Add allowed origins.
        _policy.Origins.Add("http://myclient.azurewebsites.net");
        _policy.Origins.Add("http://www.contoso.com");
    }

    public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request)
    {
        return Task.FromResult(_policy);
    }
}

A questo punto è possibile applicare l'attributo in altre posizioni che si inseriscono [EnableCors].Now you can apply the attribute any place that you would put [EnableCors].

[MyCorsPolicy]
public class TestController : ApiController
{
    .. //

Ad esempio, un provider criteri CORS personalizzato è stato possibile leggere le impostazioni da un file di configurazione.For example, a custom CORS policy provider could read the settings from a configuration file.

Come alternativa all'uso di attributi, è possibile registrare un' ICorsPolicyProviderFactory oggetto creato da ICorsPolicyProvider oggetti.As an alternative to using attributes, you can register an ICorsPolicyProviderFactory object that creates ICorsPolicyProvider objects.

public class CorsPolicyFactory : ICorsPolicyProviderFactory
{
    ICorsPolicyProvider _provider = new MyCorsPolicyProvider();

    public ICorsPolicyProvider GetCorsPolicyProvider(HttpRequestMessage request)
    {
        return _provider;
    }
}

Per impostare il ICorsPolicyProviderFactory, chiamare il SetCorsPolicyProviderFactory metodo di estensione all'avvio, come indicato di seguito:To set the ICorsPolicyProviderFactory, call the SetCorsPolicyProviderFactory extension method at startup, as follows:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.SetCorsPolicyProviderFactory(new CorsPolicyFactory());
        config.EnableCors();

        // ...
    }
}

Supporto browserBrowser support

Il pacchetto di CORS per l'API Web è una tecnologia lato server.The Web API CORS package is a server-side technology. Il browser dell'utente deve anche supportare CORS.The user's browser also needs to support CORS. Fortunatamente, includono le versioni correnti di tutti i principali browser supporto per CORS.Fortunately, the current versions of all major browsers include support for CORS.