简体   繁体   English

在 Web API 2 中启用 CORS

[英]Enable CORS in Web API 2

I have client and a server running on different ports.我有在不同端口上运行的客户端和服务器。 The server is running Web API 2 (v5.0.0-rc1) .服务器正在运行Web API 2 (v5.0.0-rc1)

I tried installing the Microsoft ASP.NET Web API Cross-Origin Support package and enabled it in WebApiConfig.cs .我尝试安装Microsoft ASP.NET Web API 跨域支持包并在WebApiConfig.cs启用它。 It gives me the EnableCors() function, so the package was installed correctly.它给了我EnableCors()函数,所以包安装正确。

Here you can see my Register() function in WebApiConfig.cs :在这里您可以在WebApiConfig.cs看到我的Register()函数:

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

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

GET requests work fine. GET请求工作正常。 But when sending POST , I get the following:但是在发送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.

According to Fiddler it only sends the OPTIONS request.根据 Fiddler,它只发送OPTIONS请求。 It doesn't issue the POST afterwards.之后它不会发出POST

So I'm guessing the config.EnableCors(cors);所以我猜是config.EnableCors(cors); in the WebApiConfig.cs isn't doing anything, which leads to the server denying the client/browser to send a POST request.WebApiConfig.cs中没有做任何事情,这会导致服务器拒绝客户端/浏览器发送POST请求。

Do you have any idea how to solve this problem?你知道如何解决这个问题吗?

EDIT 05.09.13 This has been fixed in 5.0.0-rtm-130905编辑 05.09.13这已在 5.0.0-rtm-130905 中得到修复

CORS works absolutely fine in Microsoft.AspNet.WebApi.Cors version 5.2.2. CORS 在Microsoft.AspNet.WebApi.Cors版本 5.2.2 中工作得非常好。 The following steps configured CORS like a charm for me:以下步骤将 CORS 配置为对我来说很有吸引力:

  1. Install-Package Microsoft.AspNet.WebApi.Cors -Version "5.2.2" // run from Package manager console Install-Package Microsoft.AspNet.WebApi.Cors -Version "5.2.2" // 从包管理器控制台运行
  2. In Global.asax, add the following line: BEFORE ANY MVC ROUTE REGISTRATIONS在 Global.asax 中,添加以下行: BEFORE ANY MVC ROUTE REGISTRATIONS

     GlobalConfiguration.Configure(WebApiConfig.Register);
  3. In the WebApiConfig Register method, have the following code:WebApiConfig Register 方法中,有以下代码:

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

In the web.config, the following handler must be the first one in the pipeline:在 web.config 中,以下处理程序必须是管道中的第一个:

<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

In the controller derived from ApiController , add the EnableCorsAttribute :在从ApiController派生的控制器中,添加EnableCorsAttribute

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

That should set you up nicely!那应该很好地设置你!

I didn't need to install any package.我不需要安装任何软件包。 Just a simple change in your WebAPI project's web.config is working great:只需对您的 WebAPI 项目的 web.config 进行一个简单的更改就可以很好地工作:

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

Credit goes to: Using CORS in ASP.NET WebAPI Without Being a Rocket Scientist 归功于在 ASP.NET WebAPI 中使用 CORS 而不是火箭科学家

For reference using the [EnableCors()] approach will not work if you intercept the Message Pipeline using a DelegatingHandler .如果您使用DelegatingHandler拦截消息管道,则使用[EnableCors()]方法作为参考将不起作用。 In my case was checking for an Authorization header in the request and handling it accordingly before the routing was even invoked, which meant my request was getting processed earlier in the pipeline so the [EnableCors()] had no effect.在我的情况下,检查请求中的Authorization标头并在调用路由之前相应地处理它,这意味着我的请求在管道中更早地得到处理,因此[EnableCors()]不起作用。

In the end found an example CrossDomainHandler class (credit to shaunxu for the Gist ) which handles the CORS for me in the pipeline and to use it is as simple as adding another message handler to the pipeline.最后找到了一个示例CrossDomainHandlerGist归功于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);
            }
        }
    }

To use it add it to the list of registered message handlers要使用它,请将其添加到已注册的消息处理程序列表中

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

Any preflight requests by the Browser are handled and passed on, meaning I didn't need to implement an [HttpOptions] IHttpActionResult method on the Controller.浏览器的任何预检请求都会被处理和传递,这意味着我不需要在控制器上实现[HttpOptions] IHttpActionResult方法。

I'm most definitely hitting this issue with attribute routing.我肯定会通过属性路由解决这个问题 The issue was fixed as of 5.0.0-rtm-130905.该问题已从 5.0.0-rtm-130905 开始修复 But still, you can try out the nightly builds which will most certainly have the fix.但是,您仍然可以尝试夜间构建,这肯定会得到修复。

To add nightlies to your NuGet package source, go to Tools -> Library Package Manager -> Package Manager Settings and add the following URL under Package Sources : http://myget.org/F/aspnetwebstacknightly要将 nightlies 添加到 NuGet 包源,请转到Tools -> Library Package Manager -> Package Manager Settings并在Package Sources下添加以下 URL: http : //myget.org/F/aspnetwebstacknightly

Make sure that you are accessing the WebAPI through HTTPS.确保您通过 HTTPS 访问 WebAPI。

I also enabled cors in the WebApi.config.我还在 WebApi.config 中启用了 cors。

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

But my CORS request did not work until I used HTTPS urls.但是我的 CORS 请求在我使用 HTTPS url 之前不起作用。

Late reply for future reference.迟回复以备将来参考。 What was working for me was enabling it by nuget and then adding custom headers into web.config.对我有用的是通过 nuget 启用它,然后将自定义标头添加到 web.config 中。

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

 var constraints = new {httpMethod = new HttpMethodConstraint(HttpMethod.Options)};
 config.Routes.IgnoreRoute("OPTIONS", "*pathInfo",constraints);

To enable CORS, 1.Go to App_Start folder.要启用 CORS, 1. 转到 App_Start 文件夹。 2.add the namespace 'using System.Web.Http.Cors'; 2.添加命名空间'using System.Web.Http.Cors'; 3.Open the WebApiConfig.cs file and type the following in a static method. 3.打开WebApiConfig.cs文件,在静态方法中输入以下内容。

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

Below code worked for me,下面的代码对我有用,

App_Start -> WebApiConfig App_Start -> WebApiConfig

EnableCorsAttribute cors = new EnableCorsAttribute("\*", "\*", "GET,HEAD,POST");
config.EnableCors(cors);

As far as I understood, the server got to have a header that specifies that Access from Origin is Allowed ie a request from the same server could be responded to.据我了解,服务器必须有一个标头,指定允许从源访问,即可以响应来自同一服务器的请求。

I used the following code :我使用了以下代码:

// 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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM