2017-02-13 23 views
3

我在Stackoverflow找不到解決方案後解決了這個問題,所以我在這裏分享我的問題和解決方案。在.NET Core Web API上爲CORS啓用OPTIONS標頭

在使用AddCors在我的.NET Core Web Api應用程序中啓用跨域策略後,它仍然無法在瀏覽器中使用。這是因爲瀏覽器(包括Chrome和Firefox)會首先發送OPTIONS請求,而我的應用程序僅以204無內容作出響應。

+0

什麼就是失敗的特定場景?如果它「任何時候任何chrome/ff瀏覽器在做CORS時都會失敗」,那麼這個框架如何不被覆蓋?似乎這將是一個相當巨大的遺漏。 – ssmith

+0

我同意。然而,事情就是這樣。該框架將允許您使用內置功能執行CORS,但它不處理OPTIONS調用,這是從瀏覽器正常使用跨域API調用的要求。但是,您可以通過進行更簡單的調用來避免它,例如將設置類型設置爲text/plain和其他一些內容。然後瀏覽器不會首先執行OPTIONS調用。 –

回答

6

將一箇中間件類添加到您的項目中,以處理選項動詞。

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; 
     private IHostingEnvironment _environment; 

     public OptionsMiddleware(RequestDelegate next, IHostingEnvironment environment) 
     { 
      _next = next; 
      _environment = environment; 
     } 

     public async Task Invoke(HttpContext context) 
     { 
      this.BeginInvoke(context); 
      await this._next.Invoke(context); 
     } 

     private async void 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; 
       await context.Response.WriteAsync("OK"); 
      } 
     } 
    } 

    public static class OptionsMiddlewareExtensions 
    { 
     public static IApplicationBuilder UseOptions(this IApplicationBuilder builder) 
     { 
      return builder.UseMiddleware<OptionsMiddleware>(); 
     } 
    } 
} 

然後將此作爲Configure方法中Startup.cs的第一行添加app.UseOptions();

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{ 
    app.UseOptions(); 
} 
+0

我做了這件事情,可以得到點擊中間件的請求,但它返回一個「無法到達請求的URL 服務可能暫時關閉,或者它可能已永久移動到新的Web地址 [chrome socket error]:連接重置(對應於TCP RST)「錯誤。我做錯了什麼? – crackedcornjimmy

+0

我不知道。要排除故障,我會打開Fiddler並檢查請求和響應的詳細信息。 –

+3

+1,但有一件事需要調整,如果方法是options,請不要調用_next.Invoke,請求應在調用'context.Response.WriteAsync(「OK」);'後結束,所以將'Invoke'實現更改爲if(context.Request.Method!=「OPTIONS」) { await this._next.Invoke(context);如果(context.Request.Method!=「OPTIONS」) }' –

0

我知道它已被回答。只是回答最新的信息。所以它會幫助其他人。

它現在內置到asp.net核心框架中。

只要按照https://docs.microsoft.com/en-us/aspnet/core/security/cors

並更換

app.UseCors(builder => 
    builder.WithOrigins("http://example.com")); 

 app.UseCors(builder => 
     builder.WithOrigins("http://example.com") 
       .AllowAnyHeader() 
       .AllowAnyMethod() 
       .AllowCredentials()); 
相關問題