C# Asp.Net MVC WebApi CORS请求失败-未提出影响结果的解决方案
我在本地主机59569(SiteApi)上有一个Asp.Net NVC5 web应用程序(在Visual Studio 2017下运行)。我在localhost:61527(SiteClient)上有第二个网站(也在Visual Studio 2017下运行),其中一个页面一旦加载,就会对SiteApi进行以下api调用: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
$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
// 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;
}
}