Подтвердить что ты не робот

Включить CORS в Web API 2

У меня есть клиент и сервер, работающий на разных портах. Сервер работает Web API 2 (v5.0.0-rc1).

Я попробовал установить пакет поддержки веб-интерфейса Microsoft ASP.NET для нескольких сторон и включил его в 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); в WebApiConfig.cs ничего не делает, что приводит к тому, что сервер отказывает клиенту/браузеру отправлять запрос POST.

Есть ли у вас какие-либо идеи, как решить эту проблему?

РЕДАКТИРОВАТЬ 05.09.13 Это было исправлено в 5.0.0-rtm-130905

4b9b3361

Ответ 1

Я определенно ударяю эту проблему с маршрутизацией атрибутов. Проблема была исправлена ​​ с 5.0.0-rtm- 130905. Но все же вы можете попробовать ночные сборки, которые, несомненно, будут иметь исправление.

Чтобы добавить ночные часы в исходный пакет NuGet, перейдите к Tools -> Library Package Manager -> Package Manager Settings и добавьте следующий URL-адрес в Package Sources: http://myget.org/F/aspnetwebstacknightly

Ответ 2

CORS отлично работает в версии Microsoft.AspNet.WebApi.Cors версии 5.2.2. Следующие шаги сконфигурировали CORS как прелесть для меня:

  • Install-Package Microsoft.AspNet.WebApi.Cors -Version "5.2.2"//запускаем из консоли диспетчера пакетов
  • В Global.asax добавьте следующую строку: ПЕРЕД ЛЮБЫМИ РЕГИСТРАМИ МАРШРУТА MVC

    GlobalConfiguration.Configure(WebApiConfig.Register);
    
  • В методе WebApiConfig Register введите следующий код:

    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

Это должно хорошо настроить вас!

Ответ 3

Мне не нужно было устанавливать какой-либо пакет. Простое изменение в вашем проекте WebAPI web.config отлично работает:

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

Кредит: Использование CORS в ASP.NET WebAPI без участия ракетолога

Ответ 4

Поздний ответ для дальнейшего использования. То, что работало для меня, включало его nuget, а затем добавляло пользовательские заголовки в web.config.

Ответ 5

Для справки с использованием подхода [EnableCors()] не будет работать, если вы перехватите сообщение с помощью DelegatingHandler. В моем случае проверял заголовок Authorization в запросе и обрабатывал его соответственно до того, как маршрутизация была даже вызвана, что означало, что мой запрос обрабатывался ранее в конвейере, поэтому [EnableCors()] не имел никакого эффекта.

В конце нашел пример CrossDomainHandler class (кредит shaunxu для Gist), который обрабатывает 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 на контроллере.

Ответ 6

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

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

Ответ 7

Убедитесь, что вы получаете доступ к WebAPI через HTTPS.

Я также включил cors в WebApi.config.

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

Но мой CORS-запрос не работал, пока я не использовал URL-адреса HTTPS.

Ответ 8

https://dev.to/overrideveloper/cors-in-aspnet-web-api эта ссылка может помочь вам, у меня была такая же проблема, и это помогает мне найти решение, это очень полезно