使用具有多個來源的 PUT 和 DELETE 請求時如何解決 ASP.NET Web API CORS Preflight 問題?
我有一個由三個不同的 SPA 呼叫的 ASP.NET Web API。我正在為 Web API 使用 Windows 身份驗證。我最初嘗試在 Web.config 中配置 CORS,如下所示:
<httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="http://localhost:63342" /> <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE" /> <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" /> <add name="Access-Control-Allow-Credentials" value="true" /> </customHeaders> </httpProtocol>這導致了這個預檢問題:
Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin (...) is therefore not allowed access.我通過在 Global.asax.cs 中添加以下方法解決了這個問題:
protected void Application_BeginRequest() { if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS") { Response.Flush(); } }這種方法非常適合單個 SPA。我想我可以去 Web.config 並像這樣添加其他來源:
<add name="Access-Control-Allow-Origin" value="http://localhost:63342,http://localhost:63347,http://localhost:63345/>但顯然這是不允許的。這產生了以下錯誤:
The 'Access-Control-Allow-Origin' header contains multiple values (...), but only one is allowed. Origin (...) is therefore not allowed access.因此,為了嘗試解決這個問題,我改變了方法,而是決定嘗試在 WebAPIConfig.cs 上配置 CORS,在 Register 方法中,如下所示:
var cors = new EnableCorsAttribute("http://localhost:63342,http://localhost:63347,http://localhost:63345", "Origin, X-Requested-With, Content-Type, Accept", "GET, POST, PUT, DELETE"); cors.SupportsCredentials = true; config.EnableCors(cors);我認為這會起作用,但現在我在使用 PUT 和 DELETE 請求時再次遇到預檢錯誤,我不知道如何解決這個問題。我調試了 Application_BeginRequest 方法,它仍在刷新 OPTIONS 請求,所以我不知道是什麼導致了這個錯誤。有誰知道我該如何解決這個問題?
編輯:
預檢錯誤的列印:
我能夠通過進一步自定義 Global.asax.cs 中的 Application_BeginRequest 方法來解決我的問題,如下所示:
protected void Application_BeginRequest() { if (Request.HttpMethod == "OPTIONS") { Response.StatusCode = (int)HttpStatusCode.OK; Response.AppendHeader("Access-Control-Allow-Origin", Request.Headers.GetValues("Origin")[0]); Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept"); Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"); Response.AppendHeader("Access-Control-Allow-Credentials", "true"); Response.End(); } }此程式碼所做的是將失去的標頭添加到導致預檢錯誤的 OPTIONS 響應(預檢請求)中。由於我有不同的來源呼叫我的 Web API,我使用
Request.Headers.GetValues("Origin")[0])動態設置響應中的來源。在 WebApiConfig.cs 中,我仍然指定了不同的來源,但在標頭和方法上使用了萬用字元,並將其設置
SupportsCredentials為 true,如下所示:var cors = new EnableCorsAttribute("http://localhost:63342,http://localhost:63347,http://localhost:63345", "*", "*"); cors.SupportsCredentials = true; config.EnableCors(cors);此外,如果您像我一樣使用 AngularJS,則必須配置 $http 以使用憑據。這可以像這樣全域配置:
angular .module('Application') .config(['$httpProvider', function config($httpProvider) { $httpProvider.defaults.withCredentials = true; } ]);就是這樣。這解決了我的問題。如果其他人仍有問題,我建議閱讀以下出版物,這有助於我找到答案:
