it-swarm.com.ru

Веб-интерфейс MVC: на запрашиваемом ресурсе отсутствует заголовок «Access-Control-Allow-Origin»

Я перепробовал все, что написано в этой статье: http://www.asp.net/web-api/overview/security/enabling-cross-Origin-requests-in-web-api , но ничего не работает Я пытаюсь получить данные из webAPI2 (MVC5) для использования в другом домене, используя angularJS.

мой контроллер выглядит так:

namespace tapuzWebAPI.Controllers
{
    [EnableCors(origins: "http://local.tapuz.co.il", headers: "*", methods: "*", SupportsCredentials = true)]
    [RoutePrefix("api/homepage")]
    public class HomePageController : ApiController
    {
        [HttpGet]
        [Route("GetMainItems")]
        //[ResponseType(typeof(Product))]
        public List<usp_MobileSelectTopSecondaryItemsByCategoryResult> GetMainItems()
        {


            HomePageDALcs dal = new HomePageDALcs();
            //Three product added to display the data

            //HomePagePromotedItems.Value.Add(new HomePagePromotedItem.Value.FirstOrDefault((p) => p.ID == id));


            List<usp_MobileSelectTopSecondaryItemsByCategoryResult> items = dal.MobileSelectTopSecondaryItemsByCategory(3, 5);
            return items;

        }      
    }
}
107
Noa Gani

Вам необходимо включитьCORSв вашем Web Api . Самый простой и предпочтительный способ включить CORS - добавить следующее в web.config

<system.webServer>
  <httpProtocol>
    <customHeaders>
      <add name="Access-Control-Allow-Origin" value="*" />
      <add name="Access-Control-Allow-Headers" value="Content-Type" />
      <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
    </customHeaders>
  </httpProtocol>
</system.webServer>

Обратите внимание, что Methods задаются индивидуально, а не *. Это связано с тем, что при использовании * возникает ошибка.

Вы также можете включить CORS по коду.

Обновление
Требуется следующий пакет NuGet: Microsoft.AspNet.WebApi.Cors.

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.EnableCors();

        // ...
    }
}

Затем вы можете использовать атрибут [EnableCors] на Действиях или Контроллерах, как это

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

Или вы можете зарегистрировать это глобально

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        var cors = new EnableCorsAttribute("http://www.example.com", "*", "*");
        config.EnableCors(cors);

        // ...
    }
}

Вам также нужно обработать предпечатную проверку Optionsзапросы с запросами HTTP OPTIONS.

Web API должен ответить на запрос Options, чтобы подтвердить, что он действительно настроен на поддержку CORS.

Для этого все, что вам нужно сделать, это отправить empty ответ обратно. Вы можете сделать это внутри ваших действий, или вы можете сделать это глобально, как это:

# Global.asax.cs
protected void Application_BeginRequest()
{
    if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
    {
        Response.Flush();
    }
}

Эта дополнительная проверка была добавлена, чтобы гарантировать, что старые APIs, предназначенные для приема только запросов GET и POST, не будут использоваться. Представьте себе, что вы отправляете запрос DELETE в API, созданный, когда этот глагол не существует. Результат непредсказуемый, а результаты могут быть опасные.

256
Mihai-Andrei Dinculescu

Ответ @ Mihai-Andrei Dinculescu правильный, но в интересах искателей есть и тонкое замечание, которое может вызвать эту ошибку. 

Добавление символа '/' в конце вашего URL-адреса не позволит EnableCors работать во всех случаях (например, с домашней страницы).

То есть Это не будет работать

var cors = new EnableCorsAttribute("http://testing.azurewebsites.net/", "*", "*");
config.EnableCors(cors);

но это будет работать

var cors = new EnableCorsAttribute("http://testing.azurewebsites.net", "*", "*");
config.EnableCors(cors);

Эффект тот же, если использовать атрибут EnableCors.

22
HockeyJ

Я выполнил все шаги, указанные выше Михай-Андрей Динкулеску .
Но в моем случае мне потребовалось еще 1 step, потому что http OPTIONS был отключен в Web.Config в строке ниже.

<remove name="OPTIONSVerbHandler" />

Я только что удалил его из Web.Config (просто прокомментируйте, как показано ниже), и Cors работает как шарм

<handlers>
  <!-- remove name="OPTIONSVerbHandler" / -->
</handlers>
17
AlbertSY

Это может быть связано с установкой пакетов Cors nuget.

Если вы столкнулись с проблемой после установки и включения Cors из Nuget, вы можете попробовать переустановить веб-интерфейс Api.

В диспетчере пакетов запустите Update-Package Microsoft.AspNet.WebApi -reinstall

9
Bimal Das

Попробуйте, чтобы убедиться, что вы правильно настроили CORS:

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

До сих пор не работает? Проверьте наличие заголовков HTTP.

5
Andrei

Чтобы любой протокол CORS работал, вам нужно иметь метод OPTIONS на каждой конечной точке (или глобальный фильтр с этим методом), который будет возвращать эти заголовки: 

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: content-type

Причина в том, что браузер сначала отправит запрос OPTIONS для «проверки» вашего сервера и просмотра авторизаций.

4
sam

Ответ @ Михая-Андрея Динкулеску работал на меня, например:

  • Добавление <httpProtocol> в раздел <system.webServer> web.config
  • Возврат пустого ответа для запросов OPTIONS через упомянутое Application_BeginRequest() в global.asax

За исключением того, что его проверка для Request.Headers.AllKeys.Contains("Origin") НЕ работала для меня, потому что запрос содержал origing, так что строчными буквами. Я думаю, что мой браузер (Chrome) отправляет его таким образом для запросов CORS. 

Я решил это более обобщенно, используя без учета регистра вариант его проверки Contains вместо: if (culture.CompareInfo.IndexOf(string.Join(",", Request.Headers.AllKeys), "Origin", CompareOptions.IgnoreCase) >= 0) {

1
Bart

Я поймал следующий случай о корсах. Может быть, это кому-нибудь пригодится . Если вы добавите функцию 'WebDav Redirector' на ваш сервер, запросы PUT и DELETE будут неудачными.

Итак, вам нужно удалить «WebDAVModule» с вашего IIS сервера:

  • «В конфигурации модулей IIS зациклируйте модуль WebDAVModule, если он есть на вашем веб-сервере, а затем удалите его».

Или добавьте в свой конфиг:

<system.webServer>
<modules>
  <remove name="WebDAVModule"/>
</modules>
<handlers>
  <remove name="WebDAV" />
  ...
</handlers>

0
Andrey R

Я перепробовал все, что мог найти в сети, включая методы, которые были даны в этом ответе. После почти полной попытки решить проблему в течение целого дня я нашел решение, которое сработало для меня, как шарм.

в файле WebApiConfig в папке App_Start закомментируйте все строки кода и добавьте следующий код:

`public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        config.EnableCors();
        var enableCorsAttribute = new EnableCorsAttribute("*",
                                           "Origin, Content-Type, Accept",
                                           "GET, PUT, POST, DELETE, OPTIONS");
        config.EnableCors(enableCorsAttribute);
        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            //routeTemplate: "api/{controller}/{id}",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
        config.Formatters.Add(new BrowserJsonFormatter());
    }

    public class BrowserJsonFormatter : JsonMediaTypeFormatter
    {
        public BrowserJsonFormatter()
        {
            this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
            this.SerializerSettings.Formatting = Formatting.Indented;
        }

        public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
        {
            base.SetDefaultContentHeaders(type, headers, mediaType);
            headers.ContentType = new MediaTypeHeaderValue("application/json");
        }
    }`
0
Yagnesh Khamar

Если в вашем файле web.config есть узлы security\requestFiltering, выполните следующие действия:

<security>
  <requestFiltering>
    <verbs allowUnlisted="false">
      <add verb="GET" allowed="true" />
      <add verb="POST" allowed="true" />
      <add verb="PUT" allowed="true" />
      <add verb="DELETE" allowed="true" />
      <add verb="DEBUG" allowed="true" />          
    </verbs>
  </requestFiltering>

не забудьте добавить это

<add verb="OPTIONS" allowed="true" />
0
ozz