我的CORS问题只发生在Edge和IE11中。 Chrome工作正常。
我的设置是一个ASP.NET MVC5应用程序(客户端),它有一个脚本调用一个单独的ASP.NET MVC5应用程序(API),它只包含WebAPI控制器。两个应用程序中的安全性都是通过Windows身份验证。
目前,在开发过程中,一切都在localhost上运行。
当客户端脚本调用API时,OPTIONS预检工作正常。但是,当GET
发生时,Edge和IE会出现以下错误:
在此图片中,localhost:50281
是客户端,localhost:47205
是API。
奇怪的是,呼叫实际上并没有击中控制器。控制器使用自定义AuthorizeAttribute
进行修饰,并且其中的断点不会被击中。
的Global.asax.cs
protected void Application_BeginRequest()
{
if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
{
Response.Headers.Add("Access-Control-Allow-Origin", "http://localhost:50281");
// Yes, there are too many headers. I've been working on this a while, and there are a few overkill options that have crept in
Response.Headers.Add("Access-Control-Allow-Headers", "X-AspNet-Version,X-Powered-By,Date,Server,Accept,Accept-Encoding,Accept-Language,Cache-Control,Connection,Content-Length,Content-Type,Host,Origin,Pragma,Referer,User-Agent");
Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, HEAD, OPTIONS");
Response.Headers.Add("Access-Control-Allow-Credentials", "true");
Response.Headers.Add("Access-Control-Max-Age", "600");
Response.End();
}
}
WebApiConfig.cs
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
var cors = new EnableCorsAttribute("http://localhost:50281", "*", "*");
cors.SupportsCredentials = true;
cors.PreflightMaxAge = 600;
config.EnableCors(cors);
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
GetStatus = () => {
$.ajax({
type: "GET",
url: apiUrl,
dataType: "json",
crossDomain: true,
xhrFields: {
withCredentials: true
},
contentType: "application/json; charset=UTF-8",
success: (result) => {
this.Status(result);
}
});
}
我修改了Global.asax.cs以确保每个请求都包含Access-Control-Allow-Origin和Access-Control-Allow-Credentials,如建议的那样。但是,这仍然只在Edge和IE中产生401。它在Chrome中运行良好。
这显然是我得到适当的标题。但是,出于某种原因,尽管存在withCredentials: true
,Edge和IE仍然不允许身份验证通过。我还缺少另一件吗?
答案 0 :(得分:3)
ASP.NET(OWIN)
Install-Package Microsoft.Owin.Cors
Startup.cs:
app.UseCors(CorsOptions.AllowAll)
Web配置:
<system.webServer>
<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>
</system.webServer>
答案 1 :(得分:0)
您需要使用GET请求以及预检OPTIONS请求返回Access-Control-Allow-Origin
(ACAO)和Access-Control-Allow-Credentials
(ACAC)标头。对于您通过cookie /身份验证的每个跨域请求,都需要返回这两个标头。
最佳/最简单/最干净的方法是编码,以便对包含Origin请求标头的所有请求(OPTIONS,GET,POST等)添加ACAO和ACAC标头。然后,对于OPTIONS请求,还添加其他Access-Control-Allow- *标头......
此外,对于FWIW,在ACAO标头中返回Origin请求标头的值是明智的想法,而不是将其硬编码为http://localhost:50281
。这样,如果你改变你的端口或其他什么,它仍然会起作用。