Angularjs Web API 2 CORS飞行前选项请求失败,出现504错误
我有一个WebAPI2项目,需要从一个单独的域访问。GET请求工作正常,但POST与飞行前请求一起失败。我无法获取正确返回的选项请求 我已将NuGet软件包Microsoft.AspNet.WebApi.Cors添加到项目中 在WebApiConfig.cs中,我调用:Angularjs Web API 2 CORS飞行前选项请求失败,出现504错误,angularjs,asp.net-web-api,Angularjs,Asp.net Web Api,我有一个WebAPI2项目,需要从一个单独的域访问。GET请求工作正常,但POST与飞行前请求一起失败。我无法获取正确返回的选项请求 我已将NuGet软件包Microsoft.AspNet.WebApi.Cors添加到项目中 在WebApiConfig.cs中,我调用: public static void Register(HttpConfiguration config) { config.EnableCors(); My Web.config包含
public static void Register(HttpConfiguration config)
{
config.EnableCors();
My Web.config包含以下值:
<system.webServer>
<modules>
<remove name="FormsAuthentication" />
</modules>
<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>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE,OPTIONS" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
</customHeaders>
</httpProtocol>
</system.webServer>
在Fiddler中,我看到一个请求
选项/api/app/controller HTTP/1.1
但答案是肯定的
HTTP/1.1 504 Fiddler-接收失败
AngularJS发出请求时,它有以下标题:
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://localhost:4104
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
Access-Control-Request-Headers: accept, content-type
Accept: */*
Referer: http://localhost:4104/index.html
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-GB,en-US;q=0.8,en;q=0.6
如果我使用具有相同标题的高级REST客户端Chrome插件,它也会失败。但是,如果我删除头访问控制请求方法:POST
,我将从选项请求返回一个200响应
更新: 将Global.asax.cs代码更改为
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("Cache-Control", "no-cache");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "OPTIONS, GET, POST");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.SuppressContent = true;
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
}
当从Chrome Advanced REST客户端发出请求时,我得到一个200响应代码。然而,我仍然可以从调用web api的angular代码中看到完全相同的超时
这是AngularJs代码:
$http({
method: 'POST',
url: 'http://www.test.com/api/app/controller',
data: postdata,
headers: {
'Content-Type': 'application/json'
}
})
.then(function(response) {
// Do stuff
}, function() {
// Show error
})
.finally(function() {
// Cancel loading indicator
});
我已将
应用程序_BeginRequest
的第一行更改为包含日志记录:
protected void Application_BeginRequest(object sender, EventArgs e)
{
log.Debug("Application_BeginRequest " + HttpContext.Current.Request.HttpMethod);
对于
GET
请求,此日志应用程序\u BeginRequest GET
。当AngularJS发出选项
请求时,不会记录任何内容。看起来代码是应用程序\u BeginRequest
从未被访问过。当我使用Chrome Advanced REST API从同一台机器上进行调用时,它会记录(并正常工作)。使用Global.asax中的应用程序_BeginRequest手动添加标头
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("Cache-Control", "no-cache");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.End();
}
}
我已经用我在global.asax中实现的内容更新了我的问题。抱歉,原始问题遗漏。接受此答案。另一个问题是掩盖它已修复,但这解决了问题。您是否在Web API中使用Owin管道?好问题!,
web.config
中的这一行(
)非常重要。你说对了,tnx
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("Cache-Control", "no-cache");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.End();
}
}