首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Asp.Net WebApi2使CORS无法与AspNet.WebApi.Cors 5.2.3配合使用

Asp.Net WebApi2使CORS无法与AspNet.WebApi.Cors 5.2.3配合使用
EN

Stack Overflow用户
提问于 2015-03-13 11:17:10
回答 11查看 108.1K关注 0票数 80

我尝试按照http://enable-cors.org/server_aspnet.html上的步骤让我的RESTful应用程序接口(用ASP.NET WebAPI2实现)处理跨域请求(启用CORS)。除非我修改web.config,否则它不会工作。

我安装了WebApi Cors依赖项:

代码语言:javascript
复制
install-package Microsoft.AspNet.WebApi.Cors -ProjectName MyProject.Web.Api

然后在我的App_Start中,我获得了类WebApiConfig,如下所示:

代码语言:javascript
复制
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/persons,但是在响应中我看不到应该看到的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依赖项),它就可以工作:

代码语言:javascript
复制
<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>

任何帮助都将不胜感激!

谢谢。

EN

回答 11

Stack Overflow用户

回答已采纳

发布于 2015-04-02 02:01:02

我已经为您创建了一个精简的演示项目。

您可以从本地的尝试上面的Fiddler API Link来查看标题。这里有一个解释。

Global.ascx

所有这些操作都是调用WebApiConfig。它只是一个代码组织。

代码语言:javascript
复制
public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        WebApiConfig.Register(GlobalConfiguration.Configuration);
    }
}

WebApiConfig.cs

here的关键方法是EnableCrossSiteRequests方法。这是你需要做的所有。EnableCorsAttribute是一个globally scoped CORS attribute

代码语言:javascript
复制
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);
    }
}

Values Controller

Get方法接收我们全局应用的EnableCors属性。Another方法覆盖全局EnableCors

代码语言:javascript
复制
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的样子-它是空的。

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<configuration>
</configuration>

演示

代码语言:javascript
复制
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);
});
代码语言:javascript
复制
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

票数 99
EN

Stack Overflow用户

发布于 2016-05-24 02:51:37

您只需要更改一些文件。这对我很有效。

Global.ascx

代码语言:javascript
复制
public class WebApiApplication : System.Web.HttpApplication {
    protected void Application_Start()
    {
        WebApiConfig.Register(GlobalConfiguration.Configuration);
    } }

WebApiConfig.cs

所有请求都必须调用此代码。

代码语言:javascript
复制
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中添加处理程序

代码语言:javascript
复制
<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>
票数 16
EN

Stack Overflow用户

发布于 2015-03-30 10:27:23

在CORS请求的情况下,所有现代浏览器都会使用选项动词进行响应,然后实际的请求会一直执行下去。这应该用于在CORS请求的情况下提示用户进行确认。但是对于API,如果您想跳过此验证过程,请将以下代码片段添加到Global.asax中。

代码语言:javascript
复制
        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();
            }
        }

在这里,我们只是通过检查选项动词来传递检查。

票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29024313

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档