Angularjs Web API 2 CORS飞行前选项请求失败,出现504错误

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包含

我有一个WebAPI2项目,需要从一个单独的域访问。GET请求工作正常,但POST与飞行前请求一起失败。我无法获取正确返回的选项请求

我已将NuGet软件包Microsoft.AspNet.WebApi.Cors添加到项目中

在WebApiConfig.cs中,我调用:

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();
            }
        }