在Web API 2中启用CORS

Gau*_*aui 54 c# cors asp.net-web-api

我有客户端和服务器在不同的端口上运行.服务器正在运行Web API 2(v5.0.0-rc1).

我尝试安装Microsoft ASP.NET Web API跨源支持包并启用它WebApiConfig.cs.它给了我EnableCors()功能,所以包正确安装.

在这里你可以看到我的Register()功能WebApiConfig.cs:

public static void Register(HttpConfiguration config)
{
    config.MapHttpAttributeRoutes();

    var cors = new EnableCorsAttribute("*", "*", "*");
    config.EnableCors(cors);
}
Run Code Online (Sandbox Code Playgroud)

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.
Run Code Online (Sandbox Code Playgroud)

根据Fiddler的说法,它只发送OPTIONS请求.POST之后不发布.

所以我猜测config.EnableCors(cors);WebApiConfig.cs没有做任何事情,这导致服务器拒绝客户端/浏览器发送POST请求.

你知道如何解决这个问题吗?

编辑05.09.13 这已在5.0.0-rtm-130905中修复

Sud*_*hra 59

CORS在Microsoft.AspNet.WebApi.Cors5.2.2版本中运行得非常好.以下步骤为我配置CORS就像一个魅力:

  1. Install-Package Microsoft.AspNet.WebApi.Cors -Version "5.2.2" //从包管理器控制台运行
  2. 在Global.asax中,添加以下行:在任何MVC ROUTE REGISTRATIONS之前

    GlobalConfiguration.Configure(WebApiConfig.Register);
    
    Run Code Online (Sandbox Code Playgroud)
  3. WebApiConfigRegister方法中,具有以下代码:

    public static void Register(HttpConfiguration config)
    {
        config.EnableCors();
        config.MapHttpAttributeRoutes();
    }
    
    Run Code Online (Sandbox Code Playgroud)

在web.config中,以下处理程序必须是管道中的第一个处理程序:

<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
Run Code Online (Sandbox Code Playgroud)

在派生的控制器中ApiController,添加EnableCorsAttribute:

[EnableCors(origins: "*", headers: "*", methods: "*")] // tune to your needs
[RoutePrefix("")]
public class MyController : ApiController
Run Code Online (Sandbox Code Playgroud)

这应该很好地帮助你!

  • 我只想添加,我想启用CORS,但仅在controller \ Action级别。我不希望它在全球范围内开放。但是什么都行不通,直到我在WebApiConfig中只添加了config.EnableCors()。...基本上启用了它,但是参数为0。但是然后让我在各个Controller \ Action级别使用[System.Web.Http.Cors.EnableCors(来源:“ *”,标头:“ *”,方法:“ *”)]。 (2认同)

Mos*_*ain 39

我不需要安装任何软件包.只需对WebAPI项目的web.config进行简单的更改即可:

<system.webServer>
    <httpProtocol>
        <customHeaders>
            <add name="Access-Control-Allow-Origin" value="*" />
        </customHeaders>
    </httpProtocol>
</system.webServer>
Run Code Online (Sandbox Code Playgroud)

归功于:在没有成为火箭科学家的情况下在ASP.NET WebAPI中使用CORS

  • 这样就可以了,但是如果你想在控制器/路由的基础上指定CORS,它就不起作用了. (4认同)
  • 当您建议我用于我的项目的相同技巧时,+1!讨厌 nuget 包,它完全没有必要!快乐编码兄弟! (2认同)
  • 这种方法的另一个缺点是,它导致标头包含在服务器的_every_响应中。Microsoft.AspNet.WebApi.Cors知道仅在请求包含Origin:标头时才包括它。 (2认同)

Gau*_*aui 6

我绝对是通过属性路由来解决这个问题.该问题已于5.0.0-rtm-130905 修复.但是,你仍然可以尝试夜间构建,这肯定会有修复.

要将夜莺添加到您的NuGet包源,请转到Tools -> Library Package Manager -> Package Manager Settings并添加以下URL Package Sources:http://myget.org/F/aspnetwebstacknightly


Lan*_*art 6

作为参考,[EnableCors()]如果您使用拦截消息管道,则使用该方法将不起作用DelegatingHandler。在我的情况下,正在检查Authorization请求中的标头,并在路由被调用之前进行相应的处理,这意味着我的请求在管道中更早地得到处理,因此[EnableCors()]无效。

最后,找到了一个示例CrossDomainHandler (为Gist 分配shaunxu该类我在管道中处理CORS,使用它就像在管道中添加另一个消息处理程序一样简单。

public class CrossDomainHandler : DelegatingHandler
    {
        const string Origin = "Origin";
        const string AccessControlRequestMethod = "Access-Control-Request-Method";
        const string AccessControlRequestHeaders = "Access-Control-Request-Headers";
        const string AccessControlAllowOrigin = "Access-Control-Allow-Origin";
        const string AccessControlAllowMethods = "Access-Control-Allow-Methods";
        const string AccessControlAllowHeaders = "Access-Control-Allow-Headers";

        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            bool isCorsRequest = request.Headers.Contains(Origin);
            bool isPreflightRequest = request.Method == HttpMethod.Options;
            if (isCorsRequest)
            {
                if (isPreflightRequest)
                {
                    return Task.Factory.StartNew(() =>
                    {
                        HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
                        response.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());

                        string accessControlRequestMethod = request.Headers.GetValues(AccessControlRequestMethod).FirstOrDefault();
                        if (accessControlRequestMethod != null)
                        {
                            response.Headers.Add(AccessControlAllowMethods, accessControlRequestMethod);
                        }

                        string requestedHeaders = string.Join(", ", request.Headers.GetValues(AccessControlRequestHeaders));
                        if (!string.IsNullOrEmpty(requestedHeaders))
                        {
                            response.Headers.Add(AccessControlAllowHeaders, requestedHeaders);
                        }

                        return response;
                    }, cancellationToken);
                }
                else
                {
                    return base.SendAsync(request, cancellationToken).ContinueWith(t =>
                    {
                        HttpResponseMessage resp = t.Result;
                        resp.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());
                        return resp;
                    });
                }
            }
            else
            {
                return base.SendAsync(request, cancellationToken);
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

要使用它,请将其添加到已注册消息处理程序列表中

config.MessageHandlers.Add(new CrossDomainHandler());
Run Code Online (Sandbox Code Playgroud)

浏览器的所有预检请求都会得到处理并传递,这意味着我不需要[HttpOptions] IHttpActionResult在Controller上实现方法。


tno*_*007 6

确保您正在通过HTTPS访问WebAPI。

我还在WebApi.config中启用了cors。

var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
Run Code Online (Sandbox Code Playgroud)

但是,直到我使用HTTPS网址,我的CORS请求才起作用。


小智 5

这解决了我的问题:

在Web.config>>里面system.webServer标签:

 <httpProtocol>
        <customHeaders>
            <add name="Access-Control-Allow-Origin" value="*" />
            <add name="Access-Control-Allow-Methods" value="GET,POST,PUT, DELETE, OPTIONS" />
            <add name="Access-Control-Allow-Headers" value="*" />
            <add name="Access-Control-Allow-Credentials" value="true" />
        </customHeaders>
    </httpProtocol>

Run Code Online (Sandbox Code Playgroud)

并取消注释或删除 system.webServer 中的这一行:

<remove name="OPTIONSVerbHandler"/>
Run Code Online (Sandbox Code Playgroud)

另外,您需要在 webapiconfig.cs 或 web.config 中声明启用 cors。如果您同时声明,您可能会收到类似以下错误:

'....origin 'www.example.com' blocked by cors policy due to multiple No 'Access-Control-Allow-Origin'('*','*').'
Run Code Online (Sandbox Code Playgroud)

这对我来说很有效。