Включить 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
Ответы
Ответ 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 эта ссылка может помочь вам, у меня была такая же проблема, и это помогает мне найти решение, это очень полезно