Asp.Net WebApi2 включить CORS не работает с AspNet.Веб-API.Cors 5.2.3
Я попытался выполнить шаги в http://enable-cors.org/server_aspnet.html чтобы иметь Мой RESTful API (реализованный с помощью ASP.NET WebAPI2) работа с перекрестными исходными запросами (CORS включен). Это не работает, если я не изменю веб.конфиг.
Я установил зависимость WebApi Cors:
install-package Microsoft.AspNet.WebApi.Cors -ProjectName MyProject.Web.Api
тогда в моем App_Start
у меня есть класс WebApiConfig
следующим образом:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
var corsAttr = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(corsAttr);
var constraintsResolver = new DefaultInlineConstraintResolver();
constraintsResolver.ConstraintMap.Add("apiVersionConstraint", typeof(ApiVersionConstraint));
config.MapHttpAttributeRoutes(constraintsResolver);
config.Services.Replace(typeof(IHttpControllerSelector), new NamespaceHttpControllerSelector(config));
//config.EnableSystemDiagnosticsTracing();
config.Services.Replace(typeof(ITraceWriter), new SimpleTraceWriter(WebContainerManager.Get<ILogManager>()));
config.Services.Add(typeof(IExceptionLogger), new SimpleExceptionLogger(WebContainerManager.Get<ILogManager>()));
config.Services.Replace(typeof(IExceptionHandler), new GlobalExceptionHandler());
}
}
но после этого я запускаю приложение, я запрашиваю ресурс с Fiddler как: http://localhost:51589/api/v1/persons и в ответе я не вижу заголовков HTTP, которые я должен видеть, например:
Access-Control-Allow-Methods: POST, PUT, DELETE, GET, OPTIONS
Access-Control-Allow-Origin: *
я пропустил какой-то шаг? Я пробовал со следующей аннотацией на контроллере:
[EnableCors(origins: "http://example.com", headers: "*", methods: "*")]
тот же результат, нет CORS включен.
однако, если я добавлю следующее В моей сети.конфиг (даже без установки сеть САШ.Веб-API.Пдбс зависимость) это работает:
<system.webServer>
<httpProtocol>
<!-- THESE HEADERS ARE IMPORTANT TO WORK WITH CORS -->
<!--
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="POST, PUT, DELETE, GET, OPTIONS" />
<add name="Access-Control-Allow-Headers" value="content-Type, accept, origin, X-Requested-With, Authorization, name" />
<add name="Access-Control-Allow-Credentials" value="true" />
</customHeaders>
-->
</httpProtocol>
<handlers>
<!-- THESE HANDLERS ARE IMPORTANT FOR WEB API TO WORK WITH GET,HEAD,POST,PUT,DELETE and CORS-->
<!--
<remove name="WebDAV" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,PUT,DELETE" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
-->
</handlers>
любая помощь будет высоко ценится!
спасибо.
10 ответов:
Я создал сокращенный демо-проект для вас.
- источник: https://github.com/bigfont/webapi-cors
- Api Link: https://cors-webapi.azurewebsites.net/api/values
вы можете попробовать выше API Link от вашего местного скрипача, чтобы увидеть заголовки. Вот объяснение.
глобальные.ascx
все это называется
WebApiConfig
. Это не что иное, как организация кода.public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { WebApiConfig.Register(GlobalConfiguration.Configuration); } }
WebApiConfig.cs
ключевым методом для вашего здесь является
EnableCrossSiteRequests
метод. Это все что нужно делать. ЭлементEnableCorsAttribute
это атрибут CORS с глобальной областью действия.public static class WebApiConfig { public static void Register(HttpConfiguration config) { EnableCrossSiteRequests(config); AddRoutes(config); } private static void AddRoutes(HttpConfiguration config) { config.Routes.MapHttpRoute( name: "Default", routeTemplate: "api/{controller}/" ); } private static void EnableCrossSiteRequests(HttpConfiguration config) { var cors = new EnableCorsAttribute( origins: "*", headers: "*", methods: "*"); config.EnableCors(cors); } }
Параметры Регулятора
в
Get
метод получаетEnableCors
атрибут, который мы применили глобально. ЭлементAnother
метод переопределяет глобальнуюEnableCors
.public class ValuesController : ApiController { // GET api/values public IEnumerable<string> Get() { return new string[] { "This is a CORS response.", "It works from any origin." }; } // GET api/values/another [HttpGet] [EnableCors(origins:"http://www.bigfont.ca", headers:"*", methods: "*")] public IEnumerable<string> Another() { return new string[] { "This is a CORS response. ", "It works only from two origins: ", "1. www.bigfont.ca ", "2. the same origin." }; } }
Web.конфигурации
вам не нужно добавлять ничего особенного в веб.конфиг. На самом деле, это то, что веб-демо.конфиг выглядит так-он пустой.
<?xml version="1.0" encoding="utf-8"?> <configuration> </configuration>
демо
var url = "https://cors-webapi.azurewebsites.net/api/values" $.get(url, function(data) { console.log("We expect this to succeed."); console.log(data); }); var url = "https://cors-webapi.azurewebsites.net/api/values/another" $.get(url, function(data) { console.log(data); }).fail(function(xhr, status, text) { console.log("We expect this to fail."); console.log(status); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
вам просто нужно изменить некоторые файлы. Это работает для меня.
глобальные.ascx
public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { WebApiConfig.Register(GlobalConfiguration.Configuration); } }
WebApiConfig.cs
все запросы должен вызвать этот код.
public static class WebApiConfig { public static void Register(HttpConfiguration config) { EnableCrossSiteRequests(config); AddRoutes(config); } private static void AddRoutes(HttpConfiguration config) { config.Routes.MapHttpRoute( name: "Default", routeTemplate: "api/{controller}/" ); } private static void EnableCrossSiteRequests(HttpConfiguration config) { var cors = new EnableCorsAttribute( origins: "*", headers: "*", methods: "*"); config.EnableCors(cors); } }
Какой-То Контроллер
ничего не изменится.
Web.конфигурации
вам нужно добавить обработчики в вашем интернете.конфигурации
<configuration> <system.webServer> <handlers> <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> <remove name="OPTIONSVerbHandler" /> <remove name="TRACEVerbHandler" /> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> </handlers> </system.webServer> </configuration>
в случае запроса CORS все современные браузеры отвечают глаголом OPTION, а затем следует фактический запрос. Это должно использоваться для запроса пользователя на подтверждение в случае запроса CORS. Но в случае API, если вы хотите пропустить этот процесс проверки, добавьте следующий фрагмент кода в Global.асакс
protected void Application_BeginRequest(object sender, EventArgs e) { HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); if (HttpContext.Current.Request.HttpMethod == "OPTIONS") { HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "POST, PUT, DELETE"); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept"); HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000"); HttpContext.Current.Response.End(); } }
здесь мы просто проходим проверку, проверяя глагол OPTIONS.
Я только что добавил пользовательские заголовки в Интернете.конфиг и это сработало как шарм.
конфигурация системы.веб-сервер:
<httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Headers" value="Content-Type" /> </customHeaders> </httpProtocol>
У меня есть переднее приложение и бэкэнд на том же решении. Чтобы это работало, мне нужно установить проект веб-служб (Backend) по умолчанию для этого.
Я использовал ReST, не пробовал ничего другого.
после некоторых изменений в моей сети.config CORS внезапно перестал работать в моем проекте Web API 2 (по крайней мере, для запроса параметров во время предполетного просмотра). Кажется, что вам нужно иметь раздел, упомянутый ниже в вашем интернете.config или иначе (глобальных) нем не будет работать по запросам варианты. Обратите внимание, что это тот же самый раздел, который Visual Studio добавит в новый проект Web API 2.
<system.webServer> <handlers> <remove name="ExtensionlessUrlHandler-Integrated-4.0"/> <remove name="OPTIONSVerbHandler"/> <remove name="TRACEVerbHandler"/> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0"/> </handlers> </system.webServer>
ни один из этих ответов на самом деле не работает. Как отмечали другие, пакет Cors будет использовать заголовок Access-Control-Allow-Origin только в том случае, если запрос имеет заголовок Origin. Но вы не можете просто добавить заголовок Origin к запросу, потому что браузеры могут попытаться регулировать это тоже.
Если вы хотите быстрый и грязный способ, чтобы разрешить кросс-запрос к веб-API, это действительно намного проще, просто написать пользовательский атрибут Filter:
public class AllowCors : ActionFilterAttribute { public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { if (actionExecutedContext == null) { throw new ArgumentNullException("actionExecutedContext"); } else { actionExecutedContext.Response.Headers.Remove("Access-Control-Allow-Origin"); actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Origin", "*"); } base.OnActionExecuted(actionExecutedContext); } }
тогда просто используйте его на вашем Действие контроллера:
[AllowCors] public IHttpActionResult Get() { return Ok("value"); }
Я не буду ручаться за безопасность этого в целом, но это, вероятно, намного безопаснее, чем установка заголовков в интернете.config так как таким образом вы можете применять их только так конкретно, как вам это нужно.
и конечно это просто модифицировать выше, чтобы разрешить только определенные истоки, методы и т. д.
WEBAPI2: РЕШЕНИЕ. глобальный.асакс.cs:
var cors = new EnableCorsAttribute("*", "*", "*"); config.EnableCors(cors);
в обозревателе решений щелкните правой кнопкой мыши api-project. В окне Свойства установите для параметра 'Анонимный Доступ' до включено !!!
надеюсь, это поможет кому-то в будущем.
Я только что испытал эту же проблему, пытаясь включить CORS глобально. Однако я узнал это тут работе, однако только тогда, когда запрос содержит
Origin
значение заголовка. Если вы опуститеorigin
значение заголовка, ответ не будет содержатьAccess-Control-Allow-Origin
.я использовал плагин Chrome под названием DHC чтобы проверить мой запрос GET. Это позволило мне добавить
Origin
легко заголовка.
Я нашел этот вопрос, потому что у меня возникли проблемы с запросом опций, который отправляет большинство браузеров. Мое приложение маршрутизировало запросы параметров и использовало мой IoC для создания большого количества объектов, а некоторые из них по разным причинам создавали исключения для этого странного типа запроса.
в основном положить в маршрут игнорировать для всех запросов параметров, если они вызывают у вас проблемы:
var constraints = new { httpMethod = new HttpMethodConstraint(HttpMethod.Options) }; config.Routes.IgnoreRoute("OPTIONS", "{*pathInfo}", constraints);
надеюсь, это поможет кому-то в будущем. Моя проблема заключалась в том, что я следовал тому же учебнику, что и OP, чтобы включить global CORS. Однако я также установил правило CORS для конкретных действий в своем AccountController.cs файл:
[EnableCors(origins: "", headers: "*", methods: "*")]
и получал ошибки о происхождении не может быть null или пустой строкой. Но ошибка происходила в глобальном масштабе.асакс.cs файл всех мест. Решение состоит в том, чтобы изменить его на:
[EnableCors(origins: "*", headers: "*", methods: "*")]
обратите внимание на * в истоках? Не хватало вот что было вызывая ошибку в глобальном масштабе.асакс.cs-файл.
надеюсь, это кому-то поможет.