MVC-Web-API: In der angeforderten Ressource ist kein Header 'Access-Control-Allow-Origin' vorhanden

127

Ich habe alles versucht, was in diesem Artikel geschrieben steht: http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api , aber nichts funktioniert. Ich versuche, Daten von webAPI2 (MVC5) mithilfe von angleJS in einer anderen Domäne zu verwenden.

Mein Controller sieht folgendermaßen aus:

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;

        }      
    }
}
Noa Gani
quelle
1
Teilen Sie auch Ihren
Winkelcode
2
Es gibt wahrscheinlich kein Problem mit seinem Winkelcode, da die meisten CORS-Probleme nur auf die Serverkonfiguration zurückzuführen sind
sam
Ich habe die gleiche Art von Setup. Ich habe festgestellt, dass der CORS-Header fehlt und der Browser sich beschwert, wenn ich eine nicht vorhandene Aktion in der API anfordere und WebApi eine 404 zurückgibt. Vielleicht ist es so einfach.
Robin van der Knaap

Antworten:

293

Sie müssen CORS in Ihrer Web-API aktivieren . Die einfachere und bevorzugte Möglichkeit, CORS global zu aktivieren, besteht darin, Folgendes in web.config hinzuzufügen

<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>

Bitte beachten Sie, dass die Methoden alle einzeln angegeben werden, anstatt sie zu verwenden *. Dies liegt daran, dass bei der Verwendung ein Fehler auftritt *.

Sie können CORS auch per Code aktivieren .

Update
Das folgende NuGet- Paket ist erforderlich : Microsoft.AspNet.WebApi.Cors.

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

        // ...
    }
}

Dann können Sie das [EnableCors]Attribut für Aktionen oder Controller wie diesen verwenden

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

Oder Sie können es global registrieren

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

        // ...
    }
}

Sie müssen auch die Preflight- Options Anfragen mit HTTP OPTIONSAnfragen bearbeiten .

Web APImuss auf die OptionsAnfrage antworten, um zu bestätigen, dass sie tatsächlich für die Unterstützung konfiguriert ist CORS.

Um dies zu handhaben, müssen Sie lediglich eine leere Antwort zurücksenden. Sie können dies innerhalb Ihrer Aktionen oder global wie folgt tun:

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

Diese zusätzliche Prüfung wurde hinzugefügt, um sicherzustellen, dass alte APIs, die nur zum Akzeptieren bestimmt sind GETund POSTAnforderungen nicht ausgenutzt werden. Stellen Sie sich vor, Sie senden eine DELETEAnfrage an einen APIEntwurf, wenn dieses Verb nicht existiert. Das Ergebnis ist unvorhersehbar und die Ergebnisse können gefährlich sein .

Mihai-Andrei Dinculescu
quelle
3
Ihre Antwort hat mir geholfen. Ich hatte mit den Code-Basislösungen alles versucht, was ich konnte. Ich habe die Option web.config erst ausprobiert, als ich Ihre Antwort gelesen habe. Es war das einzige, das funktionierte. Irgendeine Idee warum? Ich verwende Web API 2 mit OData. Danke trotzdem! :)
Felipe Correa
1
Für zukünftige Referenz ist das NuGet-Paket, das Sie hierfür benötigen, "Microsoft.AspNet.WebApi.Cors".
BrainSlugs83
2
Ich habe alle Ihre Antworten befolgt und zwei Fragen: Wo soll Application_BeginRequest () aufgerufen werden? und zweitens kompiliert .Contains ("Origin") in derselben Methode nicht wirklich bei mir. Woher stammt diese Methode, String.Contains oder Linq.Contains?
MeJustAndrew
2
Denken Sie daran, dass ein anderer Port # eine andere Domain darstellt, die ein Gotcha sein kann. foo.com ist eine andere Domain als foo.com:8080
RyBolt
1
Du
rettest
26

@ Mihai-Andrei Dinculescus Antwort ist richtig, aber zum Nutzen der Suchenden gibt es auch einen subtilen Punkt, der diesen Fehler verursachen kann.

Das Hinzufügen eines '/' am Ende Ihrer URL verhindert, dass EnableCors in allen Fällen funktioniert (z. B. auf der Startseite).

Dh das wird nicht funktionieren

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

aber das wird funktionieren:

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

Der Effekt ist der gleiche, wenn das EnableCors-Attribut verwendet wird.

HockeyJ
quelle
Vielen Dank!! Es war hilfreich.
Ankit Sahrawat
23

Ich folgte allen oben von Mihai-Andrei Dinculescu angegebenen Schritten .
In meinem Fall benötigte ich jedoch noch einen Schritt, da http OPTIONS in der Web.Config in der folgenden Zeile deaktiviert war.

<remove name="OPTIONSVerbHandler" />

Ich habe es gerade aus Web.Config entfernt (kommentiere es einfach wie unten) und Cors funktioniert wie ein Zauber

<handlers>
  <!-- remove name="OPTIONSVerbHandler" / -->
</handlers>
AlbertSY
quelle
9

Dies kann an der Installation von Cors Nuget-Paketen liegen.

Wenn Sie nach der Installation und Aktivierung von cors von nuget auf das Problem stoßen, können Sie versuchen, die Web-API neu zu installieren.

Führen Sie im Paketmanager aus Update-Package Microsoft.AspNet.WebApi -reinstall

Bimal Das
quelle
Das war genau das für mich. Ich habe System.Web.Http.Cors installiert und dann deinstalliert, wodurch WebApi zwischen 5.2.2 und 5.2.3 auf der falschen (neu aktualisierten) Version
belassen wurde
7

Versuchen Sie Folgendes, um sicherzustellen, dass Sie CORS richtig konfiguriert haben:

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

Funktioniert immer noch nicht? Überprüfen Sie das Vorhandensein von HTTP-Headern.

Andrei
quelle
Um zu überprüfen, ob es funktioniert, ist es besser, supportCredentials zu entfernen. Unter bestimmten Bedingungen deaktiviert es cors
harishr
Beste Antwort, da ich CORS nicht für meine gesamte Site aktivieren möchte, sondern nur für bestimmte Endpunkte. config.EnableCors()wird auch dafür benötigt.
Csaba Toth
4

Damit ein CORS-Protokoll funktioniert, benötigen Sie auf jedem Endpunkt eine OPTIONS-Methode (oder einen globalen Filter mit dieser Methode), die die folgenden Header zurückgibt:

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

Der Grund dafür ist, dass der Browser zuerst eine OPTIONS-Anforderung sendet, um Ihren Server zu testen und die Berechtigungen anzuzeigen

Sam
quelle
2

Ich fange den nächsten Fall über Cors. Vielleicht ist es für jemanden nützlich. Wenn Sie Ihrem Server die Funktion 'WebDav Redirector' hinzufügen, sind PUT- und DELETE-Anforderungen fehlgeschlagen.

Sie müssen also 'WebDAVModule' von Ihrem IIS-Server entfernen:

  • "Führen Sie in der Konfiguration der IIS-Module eine Schleife für das WebDAVModule durch. Wenn Ihr Webserver darüber verfügt, entfernen Sie es."

Oder fügen Sie Ihrer Konfiguration hinzu:

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

Andrey R.
quelle
2

Ich weiß, dass ich sehr spät dazu komme. Für jeden, der sucht, dachte ich jedoch, ich würde veröffentlichen, was ENDLICH für mich funktioniert. Ich behaupte nicht, dass es die beste Lösung ist - nur, dass es funktioniert hat.

Unser WebApi-Dienst verwendet die Methode config.EnableCors (corsAttribute). Trotzdem würde es bei den Anfragen vor dem Flug immer noch fehlschlagen. @ Mihai-Andrei Dinculescus Antwort lieferte den Hinweis für mich. Zuerst habe ich seinen Application_BeginRequest () - Code hinzugefügt, um die Optionsanforderungen zu leeren. Das hat bei mir NOCH nicht funktioniert. Das Problem ist, dass WebAPI der OPTIONS-Anforderung immer noch keinen der erwarteten Header hinzufügte. Das Spülen alleine hat nicht funktioniert - aber es gab mir eine Idee. Ich habe die benutzerdefinierten Header hinzugefügt, die andernfalls über die web.config zur Antwort auf die OPTIONS-Anforderung hinzugefügt würden. Hier ist mein Code:

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();
  }
}

Dies gilt natürlich nur für die OPTIONS-Anforderungen. Alle anderen Verben werden von der CORS-Konfiguration behandelt. Wenn es einen besseren Ansatz gibt, bin ich ganz Ohr. Es fühlt sich für mich wie ein Betrug an und ich würde es vorziehen, wenn die Header automatisch hinzugefügt würden, aber das hat endlich funktioniert und mir erlaubt, weiterzumachen.

John Groft
quelle
1

@ Mihai-Andrei Dinculescus Antwort hat bei mir funktioniert, zB:

  • Hinzufügen eines <httpProtocol>im <system.webServer>Abschnitt web.config
  • Rückgabe einer leeren Antwort auf OPTIONSAnfragen über die Application_BeginRequest()inglobal.asax

Nur dass sein Scheck für Request.Headers.AllKeys.Contains("Origin")NICHT für mich funktioniert hat, weil die Anfrage ein origing, also mit Kleinbuchstaben, enthielt . Ich denke, mein Browser (Chrome) sendet es für CORS-Anfragen so.

Ich habe dies etwas allgemeiner gelöst, indem ich stattdessen eine Variante seines ContainsSchecks verwendet habe, bei der die Groß- und Kleinschreibung nicht berücksichtigt wurde: if (culture.CompareInfo.IndexOf(string.Join(",", Request.Headers.AllKeys), "Origin", CompareOptions.IgnoreCase) >= 0) {

Bart
quelle
0

Wenn Ihre web.config über Sicherheitsknoten \ requestFiltering verfügt, gehen Sie wie folgt vor:

<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>

Stellen Sie sicher, dass Sie dies ebenfalls hinzufügen

<add verb="OPTIONS" allowed="true" />
ozz
quelle
0

Ich hatte alles versucht, was ich im Internet finden konnte, einschließlich der Methoden, die für diese Antwort angegeben wurden. Nachdem ich fast den ganzen Tag versucht habe, das Problem zu lösen, habe ich die Lösung gefunden, die für mich wie ein Zauber funktioniert hat.

Kommentieren Sie in der Datei WebApiConfig im Ordner App_Start alle Codezeilen und fügen Sie den folgenden Code hinzu:

`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");
        }
    }`
Yagnesh Khamar
quelle
0

Ich weiß, dass die Leute dies wahrscheinlich zuerst sehr offensichtlich finden werden, aber denken Sie wirklich darüber nach. Dies kann oft passieren, wenn Sie etwas falsch gemacht haben.

Zum Beispiel hatte ich dieses Problem, weil ich meiner Hosts-Datei keinen Host-Eintrag hinzugefügt habe. Das eigentliche Problem war die DNS-Auflösung. Oder ich habe gerade die Basis-URL falsch verstanden.

Manchmal erhalte ich diesen Fehler, wenn das Identitätstoken von einem Server stammt, aber ich versuche, es auf einem anderen zu verwenden.

Manchmal wird dieser Fehler angezeigt, wenn die Ressource falsch ist.

Dies kann auftreten, wenn Sie die CORS-Middleware zu spät in die Kette einfügen.

Bluebaron
quelle
0

Vermeiden Sie die Aktivierung von CORS an mehreren Stellen, wie z. B. WebApiCOnfig.cs, GrantResourceOwnerCredentials-Methode im Provider- und Controller-Header-Attribut usw. Nachfolgend finden Sie eine Liste, die auch die Zugriffssteuerung "Origin zulassen" verursacht

  1. Web hat Probleme bei der Interaktion mit der von Ihnen verwendeten Datenbank.
  2. AWS Cloud Wenn VPC von Web-API und DB unterschiedlich sind.

Der folgende Code ist mehr als genug, um den Ursprung der Zugriffskontrolle zu korrigieren. // Stellen Sie sicher, dass app.UseCors ganz oben in der Codezeile der Konfiguration steht.

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

Dies verlangsamte mein Problem.

Scharade
quelle
0

Dieses Problem tritt auf, wenn Sie versuchen, von einer anderen Domäne oder einem anderen Port aus darauf zuzugreifen.

Wenn Sie Visual Studio verwenden, gehen Sie zu Extras> NuGet Package Manager> Package Manager-Konsole. Dort müssen Sie das NuGet-Paket Microsoft.AspNet.WebApi.Cors installieren

Install-Package Microsoft.AspNet.WebApi.Cors

Aktivieren Sie dann unter PROJECT> App_Start> WebApiConfig 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:"*"));

        ....

    }
}

Erstellen Sie nach erfolgreicher Installation die Lösung, und das sollte ausreichen

Tiago Martins Peres 李大仁
quelle