Ich habe versucht, die Schritte unter http://enable-cors.org/server_aspnet.html zu befolgen , damit meine RESTful-API (implementiert mit ASP.NET WebAPI2) mit Cross-Origin-Anforderungen (CORS Enabled) funktioniert. Es funktioniert nur, wenn ich die web.config ändere.
Ich habe die WebApi Cors-Abhängigkeit installiert:
install-package Microsoft.AspNet.WebApi.Cors -ProjectName MyProject.Web.Api
Dann habe App_Start
ich in meiner Klasse WebApiConfig
wie folgt:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
var corsAttr = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(corsAttr);
var constraintsResolver = new DefaultInlineConstraintResolver();
constraintsResolver.ConstraintMap.Add("apiVersionConstraint", typeof(ApiVersionConstraint));
config.MapHttpAttributeRoutes(constraintsResolver);
config.Services.Replace(typeof(IHttpControllerSelector), new NamespaceHttpControllerSelector(config));
//config.EnableSystemDiagnosticsTracing();
config.Services.Replace(typeof(ITraceWriter), new SimpleTraceWriter(WebContainerManager.Get<ILogManager>()));
config.Services.Add(typeof(IExceptionLogger), new SimpleExceptionLogger(WebContainerManager.Get<ILogManager>()));
config.Services.Replace(typeof(IExceptionHandler), new GlobalExceptionHandler());
}
}
Aber nachdem ich die Anwendung ausgeführt habe, fordere ich eine Ressource mit Fiddler an, wie: http: // localhost: 51589 / api / v1 / personen, und in der Antwort kann ich die HTTP-Header nicht sehen, die ich sehen sollte, wie:
Access-Control-Allow-Methods: POST, PUT, DELETE, GET, OPTIONS
Access-Control-Allow-Origin: *
Vermisse ich einen Schritt? Ich habe es mit folgender Anmerkung auf dem Controller versucht:
[EnableCors(origins: "http://example.com", headers: "*", methods: "*")]
Gleiches Ergebnis, kein CORS aktiviert.
Wenn ich jedoch Folgendes in meine web.config einfüge (ohne die AspNet.WebApi.Cors-Abhängigkeit zu installieren), funktioniert dies:
<system.webServer>
<httpProtocol>
<!-- THESE HEADERS ARE IMPORTANT TO WORK WITH CORS -->
<!--
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="POST, PUT, DELETE, GET, OPTIONS" />
<add name="Access-Control-Allow-Headers" value="content-Type, accept, origin, X-Requested-With, Authorization, name" />
<add name="Access-Control-Allow-Credentials" value="true" />
</customHeaders>
-->
</httpProtocol>
<handlers>
<!-- THESE HANDLERS ARE IMPORTANT FOR WEB API TO WORK WITH GET,HEAD,POST,PUT,DELETE and CORS-->
<!--
<remove name="WebDAV" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,PUT,DELETE" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
-->
</handlers>
Jede Hilfe wäre sehr dankbar!
Vielen Dank.
quelle
Antworten:
Ich habe ein reduziertes Demo-Projekt für Sie erstellt.
Sie können den obigen API-Link von Ihrem lokalen Fiddler aus ausprobieren , um die Header anzuzeigen. Hier ist eine Erklärung.
Global.ascx
Alles was dies tut, ist die
WebApiConfig
. Es ist nichts als Code-Organisation.public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { WebApiConfig.Register(GlobalConfiguration.Configuration); } }
WebApiConfig.cs
Die Schlüsselmethode für Ihr hier ist die
EnableCrossSiteRequests
Methode. Das ist alles was Sie tun müssen. DasEnableCorsAttribute
ist ein global scoped CORS - Attribut .public static class WebApiConfig { public static void Register(HttpConfiguration config) { EnableCrossSiteRequests(config); AddRoutes(config); } private static void AddRoutes(HttpConfiguration config) { config.Routes.MapHttpRoute( name: "Default", routeTemplate: "api/{controller}/" ); } private static void EnableCrossSiteRequests(HttpConfiguration config) { var cors = new EnableCorsAttribute( origins: "*", headers: "*", methods: "*"); config.EnableCors(cors); } }
Wertecontroller
Die
Get
Methode erhält dasEnableCors
Attribut, das wir global angewendet haben. DieAnother
Methode überschreibt die globaleEnableCors
.public class ValuesController : ApiController { // GET api/values public IEnumerable<string> Get() { return new string[] { "This is a CORS response.", "It works from any origin." }; } // GET api/values/another [HttpGet] [EnableCors(origins:"http://www.bigfont.ca", headers:"*", methods: "*")] public IEnumerable<string> Another() { return new string[] { "This is a CORS response. ", "It works only from two origins: ", "1. www.bigfont.ca ", "2. the same origin." }; } }
Web.config
Sie müssen der web.config nichts Besonderes hinzufügen. So sieht die web.config der Demo aus - sie ist leer.
<?xml version="1.0" encoding="utf-8"?> <configuration> </configuration>
Demo
var url = "https://cors-webapi.azurewebsites.net/api/values" $.get(url, function(data) { console.log("We expect this to succeed."); console.log(data); }); var url = "https://cors-webapi.azurewebsites.net/api/values/another" $.get(url, function(data) { console.log(data); }).fail(function(xhr, status, text) { console.log("We expect this to fail."); console.log(status); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
quelle
Web.config
-><customHeaders>
Sachen wie in der Frage. Ich verwende die neuesten Pakete (wie in der Frage). Irgendwelche Vorschläge, wo Sie nach dem Problem suchen können? Im Wesentlichen löst dies aus irgendeinem Grund nicht das gleiche Problem für mich."*"
für die Ursprünge in WebApiConfig verwendet. Also habe ich das"*"
In als Ursprung für das EnableCorsAttribute im Controller eingegeben und jetzt funktioniert es ohne die WebConfig. Als ich las, wie man Origins spezifiziert, glaubte ich, dass die Portnummer ungültig war, aber ich bemerkte nicht, dass das "*" in Ordnung war. Außerdem rufenconfig.EnableCors(cors);
die meisten Beispiele ohne den Parameter auf. Zum Beispiel: ( enable-cors.org/server_aspnet.html )Sie müssen nur einige Dateien ändern. Das funktioniert bei mir.
Global.ascx
public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { WebApiConfig.Register(GlobalConfiguration.Configuration); } }
WebApiConfig.cs
Alle Anfragen müssen diesen Code aufrufen.
public static class WebApiConfig { public static void Register(HttpConfiguration config) { EnableCrossSiteRequests(config); AddRoutes(config); } private static void AddRoutes(HttpConfiguration config) { config.Routes.MapHttpRoute( name: "Default", routeTemplate: "api/{controller}/" ); } private static void EnableCrossSiteRequests(HttpConfiguration config) { var cors = new EnableCorsAttribute( origins: "*", headers: "*", methods: "*"); config.EnableCors(cors); } }
Einige Controller
Nichts zu ändern.
Web.config
Sie müssen Handler in Ihrer web.config hinzufügen
<configuration> <system.webServer> <handlers> <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> <remove name="OPTIONSVerbHandler" /> <remove name="TRACEVerbHandler" /> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> </handlers> </system.webServer> </configuration>
quelle
Im Falle einer CORS-Anfrage antworten alle modernen Browser mit einem OPTION-Verb, und dann folgt die eigentliche Anfrage. Dies soll verwendet werden, um den Benutzer im Falle einer CORS-Anfrage zur Bestätigung aufzufordern. Wenn Sie jedoch im Falle einer API diesen Überprüfungsprozess überspringen möchten, fügen Sie Global.asax das folgende Snippet hinzu
protected void Application_BeginRequest(object sender, EventArgs e) { HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); if (HttpContext.Current.Request.HttpMethod == "OPTIONS") { HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "POST, PUT, DELETE"); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept"); HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000"); HttpContext.Current.Response.End(); } }
Hier bestehen wir nur die Prüfung, indem wir nach dem Verb OPTIONEN suchen.
quelle
Ich habe gerade benutzerdefinierte Header zur Web.config hinzugefügt und es hat wie ein Zauber funktioniert.
Bei der Konfiguration - system.webServer:
<httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Headers" value="Content-Type" /> </customHeaders> </httpProtocol>
Ich habe die Frontend-App und das Backend auf der gleichen Lösung. Damit dies funktioniert, muss ich das Webdienstprojekt (Backend) als Standard festlegen, damit dies funktioniert.
Ich habe ReST verwendet und nichts anderes ausprobiert.
quelle
Nach einigen Änderungen in meiner Web.config funktionierte CORS plötzlich nicht mehr in meinem Web API 2-Projekt (zumindest für OPTIONS-Anforderungen während des Preflights). Es scheint, dass Sie den unten genannten Abschnitt in Ihrer Web.config haben müssen, sonst funktioniert das (globale) EnableCorsAttribute nicht für OPTIONS-Anforderungen. Beachten Sie, dass dies genau derselbe Abschnitt ist, den Visual Studio in einem neuen Web API 2-Projekt hinzufügt.
<system.webServer> <handlers> <remove name="ExtensionlessUrlHandler-Integrated-4.0"/> <remove name="OPTIONSVerbHandler"/> <remove name="TRACEVerbHandler"/> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0"/> </handlers> </system.webServer>
quelle
Keine dieser Antworten funktioniert wirklich. Wie andere angemerkt haben, verwendet das Cors-Paket den Access-Control-Allow-Origin-Header nur, wenn die Anforderung einen Origin-Header hatte. Im Allgemeinen können Sie der Anforderung jedoch nicht einfach einen Origin-Header hinzufügen, da Browser möglicherweise auch versuchen, dies zu regulieren.
Wenn Sie schnell und unkompliziert standortübergreifende Anforderungen an eine Web-API zulassen möchten, ist es viel einfacher, einfach ein benutzerdefiniertes Filterattribut zu schreiben:
public class AllowCors : ActionFilterAttribute { public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { if (actionExecutedContext == null) { throw new ArgumentNullException("actionExecutedContext"); } else { actionExecutedContext.Response.Headers.Remove("Access-Control-Allow-Origin"); actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Origin", "*"); } base.OnActionExecuted(actionExecutedContext); } }
Verwenden Sie es dann einfach für Ihre Controller-Aktion:
[AllowCors] public IHttpActionResult Get() { return Ok("value"); }
Ich werde nicht für die Sicherheit im Allgemeinen bürgen, aber es ist wahrscheinlich viel sicherer als das Setzen der Header in der web.config, da Sie sie auf diese Weise nur so spezifisch anwenden können, wie Sie sie benötigen.
Und natürlich ist es einfach, das oben Gesagte so zu ändern, dass nur bestimmte Ursprünge, Methoden usw. zulässig sind.
quelle
Ich habe gerade das gleiche Problem festgestellt und versucht, CORS global zu aktivieren . Ich habe jedoch herausgefunden, dass es funktioniert , jedoch nur, wenn die Anforderung einen
Origin
Header-Wert enthält . Wenn Sie denorigin
Header-Wert weglassen , enthält die Antwort keinAccess-Control-Allow-Origin
.Ich habe ein Chrome-Plugin namens DHC verwendet , um meine GET-Anfrage zu testen. Dadurch konnte ich den
Origin
Header einfach hinzufügen .quelle
WEBAPI2: LÖSUNG. global.asax.cs:
var cors = new EnableCorsAttribute("*", "*", "*"); config.EnableCors(cors);
Klicken Sie im Solution Explorer mit der rechten Maustaste auf das API-Projekt. Setzen Sie im Eigenschaftenfenster 'Anonyme Authentifizierung' auf Aktiviert !!!
Hoffe das hilft jemandem in der Zukunft.
quelle
config
in global.asax.cs.Niemand mit sicherer Lösung arbeitet für mich, um sicherer als Neeraj und einfacher als Matthew zu sein. Fügen Sie einfach hinzu:
System.Web.HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
In der Methode Ihres Controllers. Diese Arbeit für mich.
public IHttpActionResult Get() { System.Web.HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); return Ok("value"); }
quelle
Ich habe diese Frage gefunden, weil ich Probleme mit der OPTIONS-Anfrage hatte, die die meisten Browser senden. Meine App leitete die OPTIONS-Anforderungen weiter und verwendete mein IoC, um viele Objekte zu erstellen. Einige haben aus verschiedenen Gründen Ausnahmen für diesen ungeraden Anforderungstyp ausgelöst.
Geben Sie im Grunde eine Ignorierroute für alle OPTIONS-Anforderungen ein, wenn diese Probleme verursachen:
var constraints = new { httpMethod = new HttpMethodConstraint(HttpMethod.Options) }; config.Routes.IgnoreRoute("OPTIONS", "{*pathInfo}", constraints);
Weitere Informationen: Stoppen Sie die Verarbeitung von OPTIONS-Anforderungen durch die Web-API
quelle
Hoffe das hilft jemandem in der Zukunft. Mein Problem war, dass ich dem gleichen Tutorial wie das OP folgte, um globales CORS zu aktivieren. Ich habe jedoch auch eine aktionsspezifische CORS-Regel in meiner AccountController.cs-Datei festgelegt:
[EnableCors(origins: "", headers: "*", methods: "*")]
und es wurden Fehler über den Ursprung angezeigt, die nicht null oder eine leere Zeichenfolge sein können. ABER der Fehler trat ausgerechnet in der Datei Global.asax.cs auf. Die Lösung besteht darin, es zu ändern in:
[EnableCors(origins: "*", headers: "*", methods: "*")]
Beachten Sie das * in den Ursprüngen? Das Fehlen war der Grund für den Fehler in der Datei Global.asax.cs.
Hoffe das hilft jemandem.
quelle