在Web API 2中启用CORS
在Web API 2中启用CORS
我在不同的端口上运行着一个客户端和一个服务器。服务器正在运行 Web API 2 (v5.0.0-rc1)。
我尝试安装了Microsoft ASP.NET Web API 跨域支持包并在 WebApiConfig.cs
中启用了它。它给我提供了 EnableCors()
函数,所以包安装正确。
下面是我在 WebApiConfig.cs
中的 Register()
函数:
public static void Register(HttpConfiguration config) { config.MapHttpAttributeRoutes(); var cors = new EnableCorsAttribute("*", "*", "*"); config.EnableCors(cors); }
GET
请求正常工作。但是当发送 POST
请求时,我收到以下错误:
OPTIONS http://localhost:19357/api/v1/rooms? 404 (Not Found) angular.js:10159 OPTIONS http://localhost:19357/api/v1/rooms? Origin http://localhost:8000 is not allowed by Access-Control-Allow-Origin. angular.js:10159 XMLHttpRequest cannot load http://localhost:19357/api/v1/rooms. Origin http://localhost:8000 is not allowed by Access-Control-Allow-Origin.
根据 Fiddler,它只发送了 OPTIONS
请求。然后没有发出 POST
请求。
所以我猜测 WebApiConfig.cs
中的 config.EnableCors(cors);
没有起作用,这导致服务器拒绝客户端/浏览器发送 POST
请求。
你有任何解决这个问题的想法吗?
编辑 05.09.13
这个问题已在 5.0.0-rtm-130905 中修复。
跨域资源共享(CORS)在Microsoft.AspNet.WebApi.Cors版本5.2.2中完全正常工作。以下步骤可以很好地配置CORS:
1. 在Package Manager控制台中运行命令:Install-Package Microsoft.AspNet.WebApi.Cors -Version "5.2.2"
2. 在Global.asax中,在任何MVC路由注册之前添加以下代码:
GlobalConfiguration.Configure(WebApiConfig.Register);
3. 在WebApiConfig的Register方法中添加以下代码:
public static void Register(HttpConfiguration config)
{
config.EnableCors();
config.MapHttpAttributeRoutes();
}
在web.config中,下面的处理程序必须是管道中的第一个:
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
在从ApiController派生的控制器中添加EnableCorsAttribute:
[EnableCors(origins: "*", headers: "*", methods: "*")] // 根据需要进行调整
[RoutePrefix("")]
public class MyController : ApiController
这样就可以很好地配置了!
请注意,这个问题在5.0.0-rtm-130905版本中已经修复了。
我只是为了完整性而添加了这些步骤:)
只想补充一下,我想启用CORS,但只想在控制器/操作级别启用它,而不是全局启用。但在我只在WebApiConfig中添加config.EnableCors()之前,什么都不起作用。基本上启用它,但参数为0。然后它允许我在个别的控制器/操作级别使用[System.Web.Http.Cors.EnableCors(origins: "", headers: "", methods: "*")]。
如何在.net 4.6.2中实现这个?
我正在使用ajax调用web api 2,并且在运行在本地的web api项目中使用了上述代码,但似乎不起作用。
你能详细说明一下什么不起作用吗?
如果要全局应用,可以在WebApiConfig中添加config.EnableCors("*","*","*"),然后在控制器中不需要声明。此外,web.config中的设置非常重要(我刚刚遇到了这个错误:))。
别忘了添加using System.Web.Http.Cors;
在添加之前,我必须先删除ExtensionlessUrlHandler-Integrated-4.0。所以这对我有效 - <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="." verb="" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
问题的原因是使用[EnableCors()]
方法无法解决问题,因为在使用DelegatingHandler
拦截消息管道时,[EnableCors()]
失效。解决方法是使用CrossDomainHandler
类来处理CORS问题,并将其添加到消息处理程序列表中。这样可以处理浏览器发出的预检请求,并且不需要在控制器上实现[HttpOptions]
IHttpActionResult
方法。问题的根源是ASP.NET Web API的CORS策略在管道的早期阶段不参与,因此如果处理程序提前返回,就必须手动提供CORS头响应。
Enable CORS in Web API 2的问题出现的原因是想要在控制器/路由的基础上指定CORS,但上述的方法无法实现。解决方法是使用Microsoft.AspNet.WebApi.Cors包。
在WebAPI项目的web.config文件中进行如下更改即可启用CORS:
然而,这种方法在使用OWIN/Katana进行托管时可能会遇到问题,因为没有web.config文件,所以推荐使用Microsoft.AspNet.WebApi.Cors包。
这种方法的另一个缺点是会在服务器的每个响应中都包含Access-Control-Allow-Origin头信息。而使用Microsoft.AspNet.WebApi.Cors包可以确保只在请求包含Origin头信息时才包含该头信息。
这种方法似乎是最简单的,但并不总是有效,与所有CORS方法一样。