Я попытался выполнить действия, указанные на странице http://enable-cors.org/server_aspnet.html чтобы мой RESTful API (реализованный с помощью ASP.NET WebAPI2) работал с запросами из разных источников (CORS включен). Это не работает, если я не изменю web.config.

Я установил зависимость 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 / people и в ответе я не вижу заголовков HTTP, которые я должен видеть, например:

  • Access-Control-Allow-Methods: POST, PUT, DELETE, GET, OPTIONS
  • Access-Control-Allow-Origin: *

Я пропустил какой-то шаг? Я пробовал использовать следующую аннотацию на контроллере:

[EnableCors(origins: "http://example.com", headers: "*", methods: "*")]

Тот же результат, без включенного CORS.

Однако, если я добавлю следующее в свой web.config (даже не устанавливая зависимость AspNet.WebApi.Cors), это сработает:

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

Любая помощь приветствуется!

Спасибо.

80
diegosasw 13 Мар 2015 в 06:17

10 ответов

Надеюсь, это поможет кому-то в будущем. Моя проблема заключалась в том, что я следовал тому же руководству, что и OP, чтобы включить глобальный CORS. Однако я также установил правило CORS для конкретного действия в моем файле AccountController.cs:

[EnableCors(origins: "", headers: "*", methods: "*")]

И получались ошибки о происхождении, не может быть пустой или пустой строкой. НО ошибка происходила во всех местах файла Global.asax.cs. Решение - изменить его на:

[EnableCors(origins: "*", headers: "*", methods: "*")]

Обратите внимание на * в происхождении? Отсутствие этого было причиной ошибки в файле Global.asax.cs.

Надеюсь, это кому-то поможет.

0
jangooni 13 Фев 2016 в 16:09

Я нашел этот вопрос, потому что у меня возникли проблемы с запросом OPTIONS, который отправляет большинство браузеров. Мое приложение маршрутизировало запросы OPTIONS и использовало мой IoC для создания множества объектов, а некоторые по разным причинам выдавали исключения для этого нечетного типа запроса.

Обычно используйте маршрут игнорирования для всех запросов OPTIONS, если они вызывают у вас проблемы:

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

Дополнительная информация: Остановить обработку запросов OPTIONS в веб-API

0
BritishDeveloper 22 Дек 2015 в 17:12

Ни одно безопасное решение не работает для меня, поэтому, чтобы быть безопаснее, чем Нирадж, и проще, чем Мэтью, просто добавьте: System.Web.HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");

В методе вашего контроллера. Это работает для меня.

public IHttpActionResult Get()
{
    System.Web.HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
    return Ok("value");
}
1
puipuix 4 Апр 2019 в 10:25

WEBAPI2: РЕШЕНИЕ. global.asax.cs:

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

В обозревателе решений щелкните правой кнопкой мыши api-project. В в окне свойств установите для Анонимной аутентификации значение Включено !!!

Надеюсь, это поможет кому-то в будущем.

1
hannes neukermans 13 Июн 2016 в 14:15

Я только что столкнулся с той же проблемой, пытаясь включить CORS глобально. Однако я обнаружил, что это действительно работает, но только тогда, когда запрос содержит значение заголовка Origin. Если вы опустите значение заголовка origin, ответ не будет содержать Access-Control-Allow-Origin.

Я использовал плагин для Chrome под названием DHC, чтобы проверить свой запрос GET. Это позволило мне легко добавить заголовок Origin.

1
Rick 16 Сен 2015 в 13:02

Ни один из этих ответов не работает. Как отмечали другие, пакет Cors будет использовать заголовок Access-Control-Allow-Origin только в том случае, если запрос имел заголовок Origin. Но обычно вы не можете просто добавить в запрос заголовок Origin, потому что браузеры также могут попытаться отрегулировать это.

Если вам нужен быстрый и грязный способ разрешить межсайтовые запросы к веб-API, действительно намного проще просто написать настраиваемый атрибут фильтра:

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");
}

Я не ручаюсь за безопасность этого в целом, но, вероятно, это намного безопаснее, чем установка заголовков в web.config, поскольку таким образом вы можете применять их только в той степени, в которой они вам нужны.

И, конечно же, это просто изменить, чтобы разрешить только определенные источники, методы и т. Д.

2
Matthew 16 Окт 2015 в 00:22

После некоторых изменений в моем Web.config CORS внезапно перестала работать в моем проекте Web API 2 (по крайней мере, для запроса OPTIONS во время предполетной проверки). Похоже, вам нужен раздел, упомянутый ниже, в вашем Web.config, иначе (глобальный) EnableCorsAttribute не будет работать с запросами OPTIONS. Обратите внимание, что это точно такой же раздел, который 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>
4
Christian Gürtler 14 Авг 2016 в 19:23

Я просто добавил настраиваемые заголовки в Web.config, и это сработало отлично.

По настройке - system.webServer:

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Headers" value="Content-Type" />
  </customHeaders>
</httpProtocol>

У меня есть интерфейсное приложение и серверная часть одного и того же решения. Чтобы это работало, мне нужно установить проект веб-служб (Backend) по умолчанию, чтобы это работало.

Я использовал ReST, больше ни с чем не пробовал.

8
Mathter 25 Май 2016 в 18:18

В случае запроса CORS все современные браузеры отвечают глаголом OPTION, а затем выполняется фактический запрос. Предполагается, что это будет использоваться для запроса подтверждения у пользователя в случае запроса CORS. Но в случае API, если вы хотите пропустить этот процесс проверки, добавьте следующий фрагмент в Global.asax

        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.

13
Neeraj 30 Мар 2015 в 02:27

Вам просто нужно изменить некоторые файлы. У меня это работает.

Global.asax

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.config

Вам нужно добавить обработчики в свой web.config

<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>
14
Bharath theorare 25 Май 2016 в 11:26