Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Asp.Net MVC WebApi CORS请求失败-未提出影响结果的解决方案_C#_Asp.net_Model View Controller_Cors_Webapi - Fatal编程技术网

C# Asp.Net MVC WebApi CORS请求失败-未提出影响结果的解决方案

C# Asp.Net MVC WebApi CORS请求失败-未提出影响结果的解决方案,c#,asp.net,model-view-controller,cors,webapi,C#,Asp.net,Model View Controller,Cors,Webapi,我在本地主机59569(SiteApi)上有一个Asp.Net NVC5 web应用程序(在Visual Studio 2017下运行)。我在localhost:61527(SiteClient)上有第二个网站(也在Visual Studio 2017下运行),其中一个页面一旦加载,就会对SiteApi进行以下api调用: $http({ url: 'http://localhost:59569/api/V2/' + alias, method: 'POST', data

我在本地主机59569(SiteApi)上有一个Asp.Net NVC5 web应用程序(在Visual Studio 2017下运行)。我在localhost:61527(SiteClient)上有第二个网站(也在Visual Studio 2017下运行),其中一个页面一旦加载,就会对SiteApi进行以下api调用:

$http({
    url: 'http://localhost:59569/api/V2/' + alias,
    method: 'POST',
    data: pm,
    xhrFields: { withCredentials: true },
    headers: { 'Content-Type': 'application/json; charset=utf-8' }
    })
    .then(th, ex);
注意:我已经尝试过使用Microsoft IE、Microsoft Edge和Chrome,在使用或不使用xhrFields+和凭据信息的情况下进行此操作

回到SiteApi,Global.asax中的以下代码截取了对选项的飞行前调用,该代码完全按照编写的代码执行,我可以在对选项的入站调用触发它时跟踪if语句

protected void Application_BeginRequest()
{
    if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
    {
        Response.Clear();
        Response.Headers.Add("Access-Control-Allow-Origin", "*");
        Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, Session");
        Response.Flush();
        Response.End();
    }
}
其目的是将所需的头发送回客户端,以允许CORS正常工作-但是,在执行此代码后,SiteClient上的网页立即返回,报告由于缺少“Access Control allow Origin”头而阻止了请求,我可以看到我没有指定任何头已经把它还给客户了

为了让CORS工作,我在SiteAPI项目上安装了以下nuget软件包

  • Microsoft.AspNet.Cors
  • Microsoft.AspNet.WebApi.Cors
我调整了WebApiConfig.Register()方法以包括:

   // Web API configuration and services
   config.EnableCors();
我已经尝试过将过滤器属性添加到控制器的多种方法,如下所示:

[EnableCors("*", "*", "*", SupportsCredentials = true)]
我已尝试从stackoverflow上的其他CORS相关问题中找到的解决方案中添加我自己的自定义ActionFilterAttribute,例如(除其他外):

我的web.config文件中包含以下内容:

<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>
响应标题:

Cache-Control: private
Content-Length: 6115
Content-Type: text/html; charset=utf-8
Date: Wed, 19 Feb 2020 00:46:06 GMT
Server: Microsoft-IIS/10.0
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
X-Powered-By: ASP.NET
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcbngyMDA4MjZcRGV2XFRlY2hJVFxFQVNJV2ViQXBwXGFwaVxWMlxHZXRDb21tYW5kcw==?=

这就是我使用的流程。有时浏览器不喜欢“*”。其他时候,浏览器也不喜欢localhost。这就是我使用的逻辑(根据需要修改allow标头)。这可能是因为您也不允许在允许的头中使用访问控制头:

[将此添加到Global.asax]

protected void Application_BeginRequest(object sender, EventArgs e)
{
        var originKey =
            Request.Headers.AllKeys.FirstOrDefault(
                a => a.Equals("origin", StringComparison.InvariantCultureIgnoreCase));

        if (originKey != null && Request.HttpMethod == "OPTIONS"))
        {
// Optional Whitelist check here can return without the headers below to reject CORS
            Response.Headers.Add("Access-Control-Allow-Origin", Request.Headers[originKey]);
            Response.Headers.Add("Access-Control-Allow-Credentials", "true");
            Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUSH, DELETE, OPTIONS");
            Response.Headers.Add("Access-Control-Allow-Headers",
                "Authorization, Content-Type, Access-Control-Allow-Headers, X-Requested-With, Access-Control-Allow-Method, Accept");

            Response.Flush();
            Response.End();
            return;
        }
}

浏览器在devtools控制台中记录的确切错误是什么?我在飞行前选项调用中得到200,在生成的数据调用中得到401。我可以单步执行飞行前调用,但即使在为API服务的代码上设置了断点,我也看不到调试API调用-我只收到401错误。我用这个代码暂时摆脱了CORS的拒绝。问题是它允许所有来源。飞行前原点调用后,我仍然得到一个401,但调试器从未捕捉到数据的实际调用。@Andrew这让一切都通过了,但您可以轻松添加一个白名单检查(我省略了这一点,因为返回“*”与返回发送的原点是一样的)。如果orignKey不是有效的Url,那么此时也可以直接返回401。至于401,您没有在这里发送任何授权头,因此如果您的端点上有[Authorized]属性,它将永远不会通过。我在控制器上有一个ActionFilterAttribute,它实现了IAAuthenticationFilter和IAAuthorizationFilter,我想这应该是为我处理的。我继承了这个项目,wile这个过滤器用于授权非CORS相关的帖子,它从不为CORS相关的帖子触发。我看不出在哪里可以添加您在处理选项请求的代码中提到的标题。嘿,安德鲁。这在global.asax中进行。您将此代码添加到受保护的无效应用程序_BeginRequest(对象发送方,EventArgs e){}Daniel,我在global.asax中逐字记录了您的代码,您可以在调试器中查看它的执行情况。我看到响应头,包括访问控制允许原点值正确的原点。飞行前期权调用成功,后续调用失败,仍被阻止。无论在何处设置断点,我都无法拦截第二个请求-在Visual Studio中从未看到它。在浏览器端,选项收到200响应,但POST收到401,并显示由于CORS策略,呼叫被阻止的消息。请求的资源上不存在Access Control Allow Origin标头。
Cache-Control: private
Content-Length: 6115
Content-Type: text/html; charset=utf-8
Date: Wed, 19 Feb 2020 00:46:06 GMT
Server: Microsoft-IIS/10.0
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
X-Powered-By: ASP.NET
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcbngyMDA4MjZcRGV2XFRlY2hJVFxFQVNJV2ViQXBwXGFwaVxWMlxHZXRDb21tYW5kcw==?=
protected void Application_BeginRequest(object sender, EventArgs e)
{
        var originKey =
            Request.Headers.AllKeys.FirstOrDefault(
                a => a.Equals("origin", StringComparison.InvariantCultureIgnoreCase));

        if (originKey != null && Request.HttpMethod == "OPTIONS"))
        {
// Optional Whitelist check here can return without the headers below to reject CORS
            Response.Headers.Add("Access-Control-Allow-Origin", Request.Headers[originKey]);
            Response.Headers.Add("Access-Control-Allow-Credentials", "true");
            Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUSH, DELETE, OPTIONS");
            Response.Headers.Add("Access-Control-Allow-Headers",
                "Authorization, Content-Type, Access-Control-Allow-Headers, X-Requested-With, Access-Control-Allow-Method, Accept");

            Response.Flush();
            Response.End();
            return;
        }
}