Asp.Net WebApi2启用CORS不能与AspNet.WebApi.Cors一起使用5.2.3
我试图按照http://enable-cors.org/server_aspnet.html上的步骤使我的RESTful API(使用ASP.NET WebAPI2实现)与跨源请求(启用CORS)一起工作。 这不工作,除非我修改web.config。
我安装了WebApi Cors依赖项:
install-package Microsoft.AspNet.WebApi.Cors -ProjectName MyProject.Web.Api
然后在我的App_Start
我有类WebApiConfig
如下:
public static class WebApiConfig { public static void Register(HttpConfiguration config) { var corsAttr = new EnableCorsAttribute("*", "*", "*"); config.EnableCors(corsAttr); var constraintsResolver = new DefaultInlineConstraintResolver(); constraintsResolver.ConstraintMap.Add("apiVersionConstraint", typeof(ApiVersionConstraint)); config.MapHttpAttributeRoutes(constraintsResolver); config.Services.Replace(typeof(IHttpControllerSelector), new NamespaceHttpControllerSelector(config)); //config.EnableSystemDiagnosticsTracing(); config.Services.Replace(typeof(ITraceWriter), new SimpleTraceWriter(WebContainerManager.Get<ILogManager>())); config.Services.Add(typeof(IExceptionLogger), new SimpleExceptionLogger(WebContainerManager.Get<ILogManager>())); config.Services.Replace(typeof(IExceptionHandler), new GlobalExceptionHandler()); } }
但之后我运行的应用程序,我请求与Fiddler的资源,如: http:// localhost:51589 / api / v1 /个人,并在响应我看不到我应该看到的HTTP标头,如:
-
Access-Control-Allow-Methods: POST, PUT, DELETE, GET, OPTIONS
-
Access-Control-Allow-Origin: *
我错过了一些步骤? 我已经在控制器上使用了以下注释:
[EnableCors(origins: "http://example.com", headers: "*", methods: "*")]
同样的结果,没有启用CORS。
但是,如果我在web.config中添加以下内容(甚至不需要安装AspNet.WebApi.Cors依赖项):
<system.webServer> <httpProtocol> <!-- THESE HEADERS ARE IMPORTANT TO WORK WITH CORS --> <!-- <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Methods" value="POST, PUT, DELETE, GET, OPTIONS" /> <add name="Access-Control-Allow-Headers" value="content-Type, accept, origin, X-Requested-With, Authorization, name" /> <add name="Access-Control-Allow-Credentials" value="true" /> </customHeaders> --> </httpProtocol> <handlers> <!-- THESE HANDLERS ARE IMPORTANT FOR WEB API TO WORK WITH GET,HEAD,POST,PUT,DELETE and CORS--> <!-- <remove name="WebDAV" /> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,PUT,DELETE" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> <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>
任何帮助将不胜感激!
谢谢。
我为你创build了一个简化的演示项目。
- 资料来源 : https : //github.com/bigfont/webapi-cors
- Api链接 : https : //cors-webapi.azurewebsites.net/api/values
您可以尝试从您当地的提琴手的上述API链接查看标题。 这是一个解释。
Global.ascx
所有这一切都是调用WebApiConfig
。 这只是代码组织。
public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { WebApiConfig.Register(GlobalConfiguration.Configuration); } }
WebApiConfig.cs
您在这里的关键方法是EnableCrossSiteRequests
方法。 这就是你需要做的一切。 EnableCorsAttribute
是一个全局作用域的CORS属性 。
public static class WebApiConfig { public static void Register(HttpConfiguration config) { EnableCrossSiteRequests(config); AddRoutes(config); } private static void AddRoutes(HttpConfiguration config) { config.Routes.MapHttpRoute( name: "Default", routeTemplate: "api/{controller}/" ); } private static void EnableCrossSiteRequests(HttpConfiguration config) { var cors = new EnableCorsAttribute( origins: "*", headers: "*", methods: "*"); config.EnableCors(cors); } }
值控制器
Get
方法接收我们全局应用的EnableCors
属性。 Another
方法覆盖全局EnableCors
。
public class ValuesController : ApiController { // GET api/values public IEnumerable<string> Get() { return new string[] { "This is a CORS response.", "It works from any origin." }; } // GET api/values/another [HttpGet] [EnableCors(origins:"http://www.bigfont.ca", headers:"*", methods: "*")] public IEnumerable<string> Another() { return new string[] { "This is a CORS response. ", "It works only from two origins: ", "1. www.bigfont.ca ", "2. the same origin." }; } }
Web.config文件
你不需要在web.config中添加任何特殊的东西。 事实上,这就是演示的web.config的外观 – 它是空的。
<?xml version="1.0" encoding="utf-8"?> <configuration> </configuration>
演示
var url = "https://cors-webapi.azurewebsites.net/api/values" $.get(url, function(data) { console.log("We expect this to succeed."); console.log(data); }); var url = "https://cors-webapi.azurewebsites.net/api/values/another" $.get(url, function(data) { console.log(data); }).fail(function(xhr, status, text) { console.log("We expect this to fail."); console.log(status); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
在CORS请求的情况下,所有现代浏览器都使用OPTION谓词进行响应,然后通过实际的请求。 这应该是用来在CORS请求的情况下提示用户确认。 但是,如果你想要跳过这个validation过程的API的情况下,将以下片段添加到Global.asax
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("Access-Control-Allow-Methods", "POST, PUT, DELETE"); 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.ascx
public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { WebApiConfig.Register(GlobalConfiguration.Configuration); } }
WebApiConfig.cs
所有的请求必须调用这个代码。
public static class WebApiConfig { public static void Register(HttpConfiguration config) { EnableCrossSiteRequests(config); AddRoutes(config); } private static void AddRoutes(HttpConfiguration config) { config.Routes.MapHttpRoute( name: "Default", routeTemplate: "api/{controller}/" ); } private static void EnableCrossSiteRequests(HttpConfiguration config) { var cors = new EnableCorsAttribute( origins: "*", headers: "*", methods: "*"); config.EnableCors(cors); } }
一些控制器
没有什么改变。
Web.config文件
您需要在web.config中添加处理程序
<configuration> <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> </configuration>
我只是将自定义标题添加到Web.config,它像一个魅力。
在configuration – system.webServer:
<httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Headers" value="Content-Type" /> </customHeaders> </httpProtocol>
我有相同的解决scheme前端应用程序和后端。 为了这个工作,我需要设置Web服务项目(后端)作为默认工作。
我正在使用ReST,还没有尝试过别的。
在我的Web.config CORS的一些修改后突然停止在我的Web API 2项目(至less在预检期间的OPTIONS请求)工作。 看来您需要在Web.config中提供以下部分,否则(全局)EnableCorsAttribute将无法在OPTIONS请求上工作。 请注意,这是Visual Studio将在新的Web API 2项目中添加的完全相同的部分。
<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>
我刚刚遇到了同样的问题,试图在全球范围内启用CORS 。 但是,我发现它确实工作,但只有当请求包含一个Origin
头值。 如果您省略origin
标题值,则该响应将不包含Access-Control-Allow-Origin
。
我使用了一个名为DHC的Chrome插件来testing我的GET请求。 它允许我轻松地添加Origin
标头。
这些答案都没有真正的工作。 正如其他人指出,如果请求有一个Origin头,Cors包将只使用Access-Control-Allow-Origin头。 但是你通常不能在请求中添加一个Origin头部,因为浏览器也可能试图调节这个。
如果你想要一个快速和肮脏的方式来允许跨网站的请求到一个Web API,只是写一个自定义的filter属性真的很容易:
public class AllowCors : ActionFilterAttribute { public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { if (actionExecutedContext == null) { throw new ArgumentNullException("actionExecutedContext"); } else { actionExecutedContext.Response.Headers.Remove("Access-Control-Allow-Origin"); actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Origin", "*"); } base.OnActionExecuted(actionExecutedContext); } }
然后在你的Controller动作上使用它:
[AllowCors] public IHttpActionResult Get() { return Ok("value"); }
一般来说,我不保证这个安全性,但是比在web.config中设置头文件可能要安全得多,因为这样你可以只按照你需要的方式来应用它们。
当然,修改上面的内容很简单,只允许某些来源,方法等。
WEBAPI2:解决scheme。 的global.asax.cs:
var cors = new EnableCorsAttribute("*", "*", "*"); config.EnableCors(cors);
在解决scheme资源pipe理器中,右键单击api-project。 在属性窗口中设置“匿名身份validation” 启用 !
希望这有助于未来的人。
我发现这个问题,因为我遇到了大多数浏览器发送的OPTIONS请求的问题。 我的应用程序路由select请求,并使用我的IoC构造大量的对象,有些人因为各种原因在这个奇怪的请求types抛出exception。
基本上所有的OPTIONS请求,如果他们导致你的问题,忽略路线:
var constraints = new { httpMethod = new HttpMethodConstraint(HttpMethod.Options) }; config.Routes.IgnoreRoute("OPTIONS", "{*pathInfo}", constraints);
更多信息: 停止Web API处理选项请求
希望这有助于未来的人。 我的问题是,我跟OP一样的教程来启用全局CORS。 不过,我也在我的AccountController.cs文件中设置了一个Action特定的CORS规则:
[EnableCors(origins: "", headers: "*", methods: "*")]
并得到有关原点不能为空或空string的错误。 但是错误发生在所有地方的Global.asax.cs文件中。 解决scheme是将其更改为:
[EnableCors(origins: "*", headers: "*", methods: "*")]
注意*在起源? 缺less这是导致Global.asax.cs文件中的错误。
希望这有助于某人。