73

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

我尝试安装Microsoft ASP.NET Web API Cross-Origin Support 包并在WebApiConfig.cs. 它给了我这个EnableCors()功能,所以包安装正确。

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

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

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

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

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

4

10 回答 10

78

CORS 在Microsoft.AspNet.WebApi.Cors5.2.2 版中工作得非常好。以下步骤配置 CORS 对我来说就像一个魅力:

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

    GlobalConfiguration.Configure(WebApiConfig.Register);
    
  3. WebApiConfigRegister 方法中,有以下代码:

    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: "*")] // tune to your needs
[RoutePrefix("")]
public class MyController : ApiController

那应该很好地设置你!

于 2014-12-08T14:20:17.817 回答
61

我不需要安装任何软件包。只需对您的 WebAPI 项目的 web.config 进行简单的更改,效果就很好:

<system.webServer>
    <httpProtocol>
        <customHeaders>
            <add name="Access-Control-Allow-Origin" value="*" />
        </customHeaders>
    </httpProtocol>
</system.webServer>

归功于:在 ASP.NET WebAPI 中使用 CORS 而不是火箭科学家

于 2015-11-06T23:24:57.233 回答
10

[EnableCors()]如果您使用DelegatingHandler. 在我的情况下,检查Authorization请求中的标头并在路由被调用之前相应地处理它,这意味着我的请求在管道中更早地得到处理,因此[EnableCors()]没有效果。

最后找到了一个示例CrossDomainHandler (归功于shaunxuGist,它在管道中为我处理 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);
            }
        }
    }

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

config.MessageHandlers.Add(new CrossDomainHandler());

浏览器的任何预检请求都会被处理和传递,这意味着我不需要[HttpOptions] IHttpActionResult在控制器上实现方法。

于 2016-09-13T16:19:50.193 回答
6

我肯定会通过属性路由来解决这个问题。从 5.0.0-rtm-130905 开始,该问题已得到修复。但是,您仍然可以尝试每晚构建,它肯定会修复。

要将 nightlies 添加到 NuGet 包源,请转到Tools -> Library Package Manager -> Package Manager Settings并添加以下 URL Package Sourceshttp ://myget.org/F/aspnetwebstacknightly

于 2013-09-05T01:53:14.390 回答
6

确保您通过 HTTPS 访问 WebAPI。

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

var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);

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

于 2019-02-21T06:05:57.813 回答
4
 var cors = new EnableCorsAttribute("*","*","*");
 config.EnableCors(cors);

 var constraints = new {httpMethod = new HttpMethodConstraint(HttpMethod.Options)};
 config.Routes.IgnoreRoute("OPTIONS", "*pathInfo",constraints);
于 2017-01-17T18:01:29.347 回答
3

迟到的答复以备将来参考。对我有用的是通过 nuget 启用它,然后将自定义标头添加到 web.config 中。

于 2014-12-15T22:17:29.650 回答
1

要启用 CORS,1.转到 App_Start 文件夹。2.添加命名空间'using System.Web.Http.Cors';3.打开 WebApiConfig.cs 文件并在静态方法中键入以下内容。

config.EnableCors(new EnableCorsAttribute("https://localhost:44328",headers:"*", methods:"*"));

于 2019-11-04T09:37:16.690 回答
0

下面的代码对我有用,

App_Start -> WebApiConfig

EnableCorsAttribute cors = new EnableCorsAttribute("\*", "\*", "GET,HEAD,POST");
config.EnableCors(cors);
于 2021-12-22T12:41:48.373 回答
-1

据我了解,服务器必须有一个标头,指定允许从源访问,即可以响应来自同一服务器的请求。

我使用了以下代码:

// create a response object of your choice
var response = Request.CreateResponse(HttpStatusCode.OK);

//add the header
//replace the star with a specific name if you want to restrict access
response.Headers.Add("Access-Control-Allow-Origin", "*");

//now you could send the response and it should work...
return response;
于 2021-04-05T05:37:58.573 回答