API Web MVC: nessuna intestazione 'Access-Control-Allow-Origin' è presente sulla risorsa richiesta


128

Ho provato tutto ciò che è scritto in questo articolo: http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api , ma nulla funziona. Sto cercando di ottenere dati da webAPI2 (MVC5) da utilizzare in un altro dominio utilizzando angularJS.

il mio controller si presenta così:

namespace tapuzWebAPI.Controllers
{
    [EnableCors(origins: "http://local.tapuz.co.il", headers: "*", methods: "*", SupportsCredentials = true)]
    [RoutePrefix("api/homepage")]
    public class HomePageController : ApiController
    {
        [HttpGet]
        [Route("GetMainItems")]
        //[ResponseType(typeof(Product))]
        public List<usp_MobileSelectTopSecondaryItemsByCategoryResult> GetMainItems()
        {


            HomePageDALcs dal = new HomePageDALcs();
            //Three product added to display the data

            //HomePagePromotedItems.Value.Add(new HomePagePromotedItem.Value.FirstOrDefault((p) => p.ID == id));


            List<usp_MobileSelectTopSecondaryItemsByCategoryResult> items = dal.MobileSelectTopSecondaryItemsByCategory(3, 5);
            return items;

        }      
    }
}

1
Condividi anche il tuo codice angolare per richiedere cors
harishr il

2
Probabilmente non c'è nessun problema con il suo codice angolare poiché la maggior parte dei problams CORS sono solo a causa della configurazione del server
sam

Ho lo stesso tipo di configurazione, ho notato che quando richiedo un'azione inesistente sull'API e WebApi restituisce un 404, manca l'intestazione CORS e il browser si lamenterà. Quindi, forse è così semplice.
Robin van der Knaap,

Risposte:


296

Devi abilitare CORS nella tua API Web . Il modo più semplice e preferito per abilitare CORS a livello globale è aggiungere quanto segue in web.config

<system.webServer>
  <httpProtocol>
    <customHeaders>
      <add name="Access-Control-Allow-Origin" value="*" />
      <add name="Access-Control-Allow-Headers" value="Content-Type" />
      <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
    </customHeaders>
  </httpProtocol>
</system.webServer>

Si noti che i metodi sono tutti specificati individualmente, anziché utilizzare *. Questo perché si verifica un bug durante l'utilizzo *.

Puoi anche abilitare CORS per codice.

Aggiornare
la seguente NuGet è richiesto Pacchetto: Microsoft.AspNet.WebApi.Cors.

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

        // ...
    }
}

Quindi è possibile utilizzare l' [EnableCors]attributo su Azioni o Controller come questo

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

Oppure puoi registrarlo a livello globale

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

        // ...
    }
}

È inoltre necessario gestire le Options richieste di verifica preliminare con HTTP OPTIONSrichieste.

Web APIdeve rispondere alla Optionsrichiesta per confermare che è effettivamente configurato per supportare CORS.

Per gestire questo, tutto ciò che devi fare è inviare una risposta vuota . Puoi farlo all'interno delle tue azioni, oppure puoi farlo globalmente in questo modo:

# Global.asax.cs
protected void Application_BeginRequest()
{
    if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
    {
        Response.Flush();
    }
}

Questo controllo aggiuntivo è stato aggiunto per garantire che i vecchi APIsche erano progettati per accettare solo GETe le POSTrichieste non fossero sfruttati. Immagina di inviare una DELETErichiesta a un APIdesign quando questo verbo non esisteva. Il risultato è imprevedibile e i risultati potrebbero essere pericolosi .


4
La tua risposta mi ha aiutato. Avevo provato tutto il possibile con le soluzioni di code base. Non ho provato l'opzione web.config finché non ho letto la tua risposta. Era l'unico che ha funzionato. Qualche idea sul perché? Sto usando l'API Web 2 con OData. Grazie comunque! :)
Felipe Correa,

1
Per riferimento futuro, il pacchetto NuGet necessario per questo è "Microsoft.AspNet.WebApi.Cors".
BrainSlugs83,

2
Ho seguito tutte le tue risposte e ho due domande: dove si dovrebbe invocare Application_BeginRequest ()? e in secondo luogo, nello stesso metodo, il .Contains ("Origin") non si compila davvero da me, da dove proviene questo metodo, String.Contains o da Linq.Contains?
meJustAndrew,

2
ricorda che una diversa porta # costituisce un dominio diverso, che può essere un gotcha. foo.com è un dominio diverso da
foo.com:8080

2
Mi hai salvato la vita;)
Paweł Groński,

26

La risposta di Mihai-Andrei Dinculescu è corretta, ma a beneficio dei ricercatori c'è anche un punto sottile che può causare questo errore.

L'aggiunta di un '/' alla fine dell'URL impedirà ad EnableCors di funzionare in tutti i casi (ad es. Dalla homepage).

Cioè Questo non funzionerà

var cors = new EnableCorsAttribute("http://testing.azurewebsites.net/", "*", "*");
config.EnableCors(cors);

ma questo funzionerà:

var cors = new EnableCorsAttribute("http://testing.azurewebsites.net", "*", "*");
config.EnableCors(cors);

L'effetto è lo stesso se si utilizza l'attributo EnableCors.


Grazie!! È stato utile.
Ankit Sahrawat,

23

Ho seguito tutti i passaggi sopra indicati da Mihai-Andrei Dinculescu .
Ma nel mio caso, avevo bisogno di un altro passo perché OPZIONI http era disabilitato in Web.Config dalla riga sottostante.

<remove name="OPTIONSVerbHandler" />

L'ho appena rimosso da Web.Config (commentalo come sotto) e Cors funziona come un fascino

<handlers>
  <!-- remove name="OPTIONSVerbHandler" / -->
</handlers>

9

Potrebbe essere a causa dell'installazione dei pacchetti nuget Cors.

Se stai affrontando il problema dopo aver installato e abilitato cors da Nuget, puoi provare a reinstallare Web Api.

Dal gestore pacchetti, eseguire Update-Package Microsoft.AspNet.WebApi -reinstall


Questo è stato esattamente per me. Ho installato System.Web.Http.Cors e poi disinstallato, il che ha lasciato WebApi sulla versione errata (appena aggiornata) tra la 5.2.2 e la 5.2.3
TaeKwonJoe,

7

Prova questo, per assicurarti di aver configurato CORS correttamente:

[EnableCors(origins: "*", headers: "*", methods: "*")]

Continua a non funzionare? Controlla la presenza delle intestazioni HTTP.


per verificare se funziona, è meglio rimuovere anche SupportCredentials, disabilita cors in determinate condizioni
harishr

La migliore risposta perché non voglio abilitare CORS per tutto il mio sito, solo per alcuni endpoint. config.EnableCors()è necessario anche per questo.
Csaba Toth,

4

Per far funzionare qualsiasi protocollo CORS, è necessario disporre di un metodo OPTIONS su ogni endpoint (o un filtro globale con questo metodo) che restituirà tali intestazioni:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: content-type

Il motivo è che il browser invierà prima una richiesta OPTIONS per "testare" il server e visualizzare le autorizzazioni


2

Prendo il prossimo caso sul cors. Forse sarà utile a qualcuno. Se aggiungi la funzione 'WebDav Redirector' al tuo server, le richieste PUT e DELETE non hanno esito positivo.

Quindi, dovrai rimuovere 'WebDAVModule' dal tuo server IIS:

  • "Nella configurazione dei moduli IIS, esegui il loop del WebDAVModule, se il tuo server web lo possiede, quindi rimuovilo".

Oppure aggiungi alla tua configurazione:

<system.webServer>
<modules>
  <remove name="WebDAVModule"/>
</modules>
<handlers>
  <remove name="WebDAV" />
  ...
</handlers>


2

So che ci arrivo molto tardi. Tuttavia, per chiunque stia cercando, ho pensato di pubblicare ciò che FINALMENTE ha funzionato per me. Non sto affermando che sia la soluzione migliore, solo che ha funzionato.

Il nostro servizio WebApi utilizza il metodo config.EnableCors (corsAttribute). Tuttavia, anche con quello, fallirebbe comunque sulle richieste pre-volo. La risposta di Mihai-Andrei Dinculescu mi ha fornito la chiave. Prima di tutto, ho aggiunto il suo codice Application_BeginRequest () per svuotare le richieste di opzioni. Che ANCORA non ha funzionato per me. Il problema è che WebAPI non stava ancora aggiungendo nessuna delle intestazioni previste alla richiesta OPTIONS. Lavarlo da solo non ha funzionato, ma mi ha dato un'idea. Ho aggiunto le intestazioni personalizzate che altrimenti sarebbero state aggiunte tramite web.config alla risposta per la richiesta OPTIONS. Ecco il mio codice:

protected void Application_BeginRequest()
{
  if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
  {
    Response.Headers.Add("Access-Control-Allow-Origin", "https://localhost:44343");
    Response.Headers.Add("Access-Control-Allow-Headers",
      "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
    Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
    Response.Headers.Add("Access-Control-Allow-Credentials", "true");
    Response.Flush();
  }
}

Ovviamente, questo vale solo per le richieste OPTIONS. Tutti gli altri verbi sono gestiti dalla configurazione CORS. Se c'è un approccio migliore a questo, sono tutto orecchie. Mi sembra un imbroglione e preferirei che le intestazioni fossero aggiunte automaticamente, ma questo è ciò che alla fine ha funzionato e mi ha permesso di andare avanti.


1

@ La risposta di Mihai-Andrei Dinculescu ha funzionato per me, ad esempio:

  • Aggiungendo un <httpProtocol>nel web.config di <system.webServer>sezione
  • Restituzione di una risposta vuota per le OPTIONSrichieste tramite il menzionato Application_BeginRequest()inglobal.asax

Solo che il suo controllo per Request.Headers.AllKeys.Contains("Origin")NON ha funzionato per me, perché la richiesta conteneva un origing, quindi con lettere minuscole. Penso che il mio browser (Chrome) lo mandi in questo modo per richieste CORS.

Ho risolto un po 'più genericamente usando invece una variante senza distinzione tra maiuscole e minuscole del suo Containscontrollo: if (culture.CompareInfo.IndexOf(string.Join(",", Request.Headers.AllKeys), "Origin", CompareOptions.IgnoreCase) >= 0) {


0

Se hai nodi security \ requestFiltering nel tuo web.config come segue:

<security>
  <requestFiltering>
    <verbs allowUnlisted="false">
      <add verb="GET" allowed="true" />
      <add verb="POST" allowed="true" />
      <add verb="PUT" allowed="true" />
      <add verb="DELETE" allowed="true" />
      <add verb="DEBUG" allowed="true" />          
    </verbs>
  </requestFiltering>

assicurati di aggiungere anche questo

<add verb="OPTIONS" allowed="true" />

0

Avevo provato tutto ciò che potevo trovare in rete, compresi i metodi che sono stati dati su questa risposta. Dopo aver quasi tentato di risolvere il problema per l'intera giornata, ho trovato la soluzione che ha funzionato per me come un incantesimo.

nel file WebApiConfig nella cartella App_Start , commentare tutte le righe di codice e aggiungere il seguente codice:

`public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        config.EnableCors();
        var enableCorsAttribute = new EnableCorsAttribute("*",
                                           "Origin, Content-Type, Accept",
                                           "GET, PUT, POST, DELETE, OPTIONS");
        config.EnableCors(enableCorsAttribute);
        // Web API routes
        config.MapHttpAttributeRoutes();

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

    public class BrowserJsonFormatter : JsonMediaTypeFormatter
    {
        public BrowserJsonFormatter()
        {
            this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
            this.SerializerSettings.Formatting = Formatting.Indented;
        }

        public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
        {
            base.SetDefaultContentHeaders(type, headers, mediaType);
            headers.ContentType = new MediaTypeHeaderValue("application/json");
        }
    }`

0

So che le persone probabilmente lo troveranno molto ovvio all'inizio, ma ci penso davvero. Questo può succedere spesso se hai fatto qualcosa di sbagliato.

Ad esempio, ho avuto questo problema perché non ho aggiunto una voce host al mio file hosts. Il vero problema era la risoluzione DNS. O ho appena sbagliato l'URL di base.

A volte ricevo questo errore se il token di identità proviene da un server, ma sto provando a usarlo su un altro.

A volte otterrai questo errore se hai sbagliato la risorsa.

Questo potrebbe verificarsi se si inserisce il middleware CORS troppo tardi nella catena.


0

Evita l'abilitazione di più posizioni CORS, come WebApiCOnfig.cs, il metodo GrantResourceOwnerCredentials nell'attributo provider e Controller Header ecc. Di seguito è riportato l'elenco che causa anche il controllo di accesso Consenti origine

  1. Web che ha problemi a interagire con il DB che hai usato.
  2. AWS Cloud Se VPC dell'API Web e del DB sono diversi.

Sotto il codice è più che sufficiente per correggere il controllo di accesso consentire origine. // Assicurati che app.UseCors sia in cima alla riga di codice di configurazione.

   public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
            //All other configurations
        }
    }

Questo ha rallentato il mio problema.


0

Questo problema si verifica quando si tenta di accedere da un dominio diverso o porta diversa.

Se stai usando Visual Studio, vai su Strumenti> Gestione pacchetti NuGet> Console Gestione pacchetti. Lì devi installare il pacchetto NuGet Microsoft.AspNet.WebApi.Cors

Install-Package Microsoft.AspNet.WebApi.Cors

Quindi, in PROJECT> App_Start> WebApiConfig, abilitare CORS

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        
        //Enable CORS. Note that the domain doesn't have / in the end.
        config.EnableCors(new EnableCorsAttribute("https://tiagoperes.eu",headers:"*",methods:"*"));

        ....

    }
}

Una volta installato correttamente, crea la soluzione e questo dovrebbe bastare

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.