使用多个来源的PUT和DELETE请求时,如何解决ASP.NET Web API CORS预检问题? [英] How to solve ASP.NET Web API CORS Preflight issue when using PUT and DELETE requests with multiple origins?
问题描述
我有一个由三个不同的SPA调用的ASP.NET Web API.我正在为Windows API使用Windows身份验证.我最初尝试像这样在Web.config中配置CORS:
I have an ASP.NET web API that is being called by three different SPA. I am using windows authentication for the web API. I initially tried to configure CORS in the Web.config like this:
<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>
这导致了此飞行前问题:
This caused this preflight issue:
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中添加以下方法解决的
:
that I solved by adding the following method in Global.asax.cs:
protected void Application_BeginRequest()
{
if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
{
Response.Flush();
}
}
此方法对于单个SPA效果很好.我以为我可以转到Web.config并添加其他类似的来源:
This approach worked perfectly for a single SPA. I thought that I could go to the Web.config and add the other origins like this:
<add name="Access-Control-Allow-Origin" value="http://localhost:63342,http://localhost:63347,http://localhost:63345/>
但显然不允许这样做.这产生了以下错误:
but apparently that is not allowed. This produced the following error:
The 'Access-Control-Allow-Origin' header contains multiple values (...), but only one is allowed. Origin (...) is therefore not allowed access.
因此,为了尝试解决此问题,我更改了方法,而是决定尝试在WebAPIConfig.cs上的Register方法中配置CORS,如下所示:
So in order to try and fix this, I changed my approach and instead decided to try to configure CORS on the WebAPIConfig.cs, in the Register method like this:
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请求,因此我不知道是什么导致了此错误.有谁知道我该如何解决这个问题?
I thought this would work but now I have the preflight error again when using PUT and DELETE requests and I don't know how to fix this. I debugged the Application_BeginRequest method and it is still flushing the OPTIONS request so I have no idea of what is causing this error. Does anyone know how I can solve this issue?
飞行前错误的打印:
推荐答案
我能够通过进一步自定义Global.asax.cs中的Application_BeginRequest方法来解决我的问题,如下所示:
I was able to solve my problem by further customizing the Application_BeginRequest method in Global.asax.cs, like this:
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])
来动态设置响应中的来源.
What this code does is add the missing headers to the OPTIONS response (preflight request) that were causing the preflight error. Since I have different origins calling my web API, I'm using Request.Headers.GetValues("Origin")[0])
to set the origin in the response dinamically.
在WebApiConfig.cs中,我仍然指定了不同的来源,但在标头和方法上使用了通配符,并将SupportsCredentials
设置为true,如下所示:
In the WebApiConfig.cs I still specified the different origins but used wildcards on the headers and methods, as well as setting the SupportsCredentials
to true, like this:
var cors = new EnableCorsAttribute("http://localhost:63342,http://localhost:63347,http://localhost:63345", "*", "*");
cors.SupportsCredentials = true;
config.EnableCors(cors);
此外,如果像我一样使用AngularJS,则必须将$ http配置为使用凭据.可以像这样全局配置:
Also, if you're using AngularJS like I am, you must configure $http to use credentials. This can be configured globally like this:
angular
.module('Application')
.config(['$httpProvider',
function config($httpProvider) {
$httpProvider.defaults.withCredentials = true;
}
]);
就是这样.这解决了我的问题.如果仍有其他问题,我建议您阅读以下出版物,这些出版物有助于我找到答案:
And that's it. This solved my problem. If someone else is still having problems, I recommend reading the following publications, which helped me reach my answer:
- http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api
- https://evolpin.wordpress.com/2012/10/12/the-cors/
- AngularJS $ http,CORS和http身份验证
- AngularJS对以下内容执行OPTIONS HTTP请求跨域资源
- AngularJS POST失败:响应for preflight具有无效的HTTP状态代码404
- http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api
- https://evolpin.wordpress.com/2012/10/12/the-cors/
- AngularJS $http, CORS and http authentication
- AngularJS performs an OPTIONS HTTP request for a cross-origin resource
- AngularJS POST Fails: Response for preflight has invalid HTTP status code 404
这篇关于使用多个来源的PUT和DELETE请求时,如何解决ASP.NET Web API CORS预检问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!