Ich habe dieses Problem gelöst, nachdem ich auf Stackoverflow keine Lösung gefunden habe. Daher teile ich mein Problem hier und die Lösung in einer Antwort.
Nach dem Aktivieren einer domänenübergreifenden Richtlinie in meiner .NET Core-Web-API-Anwendung mit AddCors funktioniert sie in Browsern immer noch nicht. Dies liegt daran, dass Browser, einschließlich Chrome und Firefox), zuerst eine OPTIONS-Anfrage senden und meine Anwendung nur mit 204 No Content antwortet.
Fügen Sie Ihrem Projekt eine Middleware-Klasse hinzu, um das Verb OPTIONS zu behandeln.
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Hosting;
namespace Web.Middlewares
{
public class OptionsMiddleware
{
private readonly RequestDelegate _next;
public OptionsMiddleware(RequestDelegate next)
{
_next = next;
}
public Task Invoke(HttpContext context)
{
return BeginInvoke(context);
}
private Task BeginInvoke(HttpContext context)
{
if (context.Request.Method == "OPTIONS")
{
context.Response.Headers.Add("Access-Control-Allow-Origin", new[] { (string)context.Request.Headers["Origin"] });
context.Response.Headers.Add("Access-Control-Allow-Headers", new[] { "Origin, X-Requested-With, Content-Type, Accept" });
context.Response.Headers.Add("Access-Control-Allow-Methods", new[] { "GET, POST, PUT, DELETE, OPTIONS" });
context.Response.Headers.Add("Access-Control-Allow-Credentials", new[] { "true" });
context.Response.StatusCode = 200;
return context.Response.WriteAsync("OK");
}
return _next.Invoke(context);
}
}
public static class OptionsMiddlewareExtensions
{
public static IApplicationBuilder UseOptions(this IApplicationBuilder builder)
{
return builder.UseMiddleware<OptionsMiddleware>();
}
}
}
Fügen Sie dann app.UseOptions();
this als erste Zeile in Startup.cs in der Configure-Methode hinzu.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseOptions();
}
Ich weiß, dass es beantwortet wurde. Antworten Sie einfach mit den aktualisierten Informationen. Also würde es anderen helfen.
Es ist jetzt in asp.net Core Framework eingebaut.
Folgen Sie einfach https://docs.Microsoft.com/en-us/aspnet/core/security/cors
und ersetzen
app.UseCors(builder =>
builder.WithOrigins("http://example.com"));
mit
app.UseCors(builder =>
builder.WithOrigins("http://example.com")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials());
Das hat bei mir funktioniert:
Stellen Sie sicher, dass dies:
app.UseCors(builder => {
AllowAnyOrigin()
AllowAnyMethod()
AllowAnyHeader()
});
Tritt vor einem der folgenden Ereignisse auf:
app.UseHttpsRedirection();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseCookiePolicy();
Denken Sie daran, wir haben es mit einer "Pipeline" zu tun. Das cors Zeug muss zuerst sein.
-gimzani
Es ist keine zusätzliche Middleware erforderlich. Wie oben bereits erwähnt, ist nur die in der Cors-Konfiguration zulässige OPTIONS-Methode erforderlich. Sie können AllowAnyMethod wie hier vorgeschlagen: https://stackoverflow.com/a/55764660/1192191
Aber es ist sicherer, nur das Folgende zuzulassen:
app.UseCors(builder => builder
.WithOrigins("https://localhost", "https://production.company.com") /* list of environments that will access this api */
.WithMethods("GET", "OPTIONS") /* assuming your endpoint only supports GET */
.WithHeaders("Origin", "Authorization") /* headers apart of safe-list ones that you use */
);
Einige Header sind immer erlaubt: https://developer.mozilla.org/en-US/docs/Glossary/CORS-safelisted_request_header
Ich wollte dies für eine einzelne Methode zulassen und keine Middleware verwenden, um dies für jede Methode zuzulassen. Dies ist, was ich getan habe:
[HttpOptions("/find")]
public IActionResult FindOptions()
{
Response.Headers.Add("Access-Control-Allow-Origin", new[] { (string)Request.Headers["Origin"] });
Response.Headers.Add("Access-Control-Allow-Headers", new[] { "Origin, X-Requested-With, Content-Type, Accept" });
Response.Headers.Add("Access-Control-Allow-Methods", new[] { "POST, OPTIONS" }); // new[] { "GET, POST, PUT, DELETE, OPTIONS" }
Response.Headers.Add("Access-Control-Allow-Credentials", new[] { "true" });
return NoContent();
}
[HttpPost("/find")]
public async Task<IActionResult> FindOptions([FromForm]Find_POSTModel model)
{
AllowCrossOrigin();
// your code...
}
private void AllowCrossOrigin()
{
Uri Origin = null;
Uri.TryCreate(Request.Headers["Origin"].FirstOrDefault(), UriKind.Absolute, out Origin);
if (Origin != null && IsOriginAllowed(Origin))
Response.Headers.Add("Access-Control-Allow-Origin", $"{Origin.Scheme}://{Origin.Host}");
}
Und natürlich können Sie IsOriginAllowed
nach Belieben implementieren
private bool IsOriginAllowed(Uri Origin)
{
const string myDomain = "mydomain.com";
const string[] allowedDomains = new []{ "example.com", "sub.example.com" };
return
allowedDomains.Contains(Origin.Host)
|| Origin.Host.EndsWith($".{myDomain}");
}
Weitere Informationen finden Sie unter Aktivieren von CORS für POST Anforderungen auf einem einzelnen Endpunkt