Веб-програма MVC: На запитуваному ресурсі немає заголовка "Access-Control-Allow-Origin"


128

Я спробував усе, що написано в цій статті: 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;

        }      
    }
}

1
Також поділіться своїм кутовим кодом для запиту
корсів

2
Там, ймовірно , не проблема з його кутовим кодом , так як більшість з CORS problams тільки через зміну сервера
Сему

У мене таке ж налаштування, я помітив, що коли я вимагаю неіснуючої дії в API, а WebApi повертає 404, заголовок CORS відсутній, і браузер скаржиться. Тож, може, це так просто.
Робін ван дер Кнаап

Відповіді:


296

Вам потрібно ввімкнути CORS у своєму веб-апі . Найпростіший і бажаний спосіб увімкнути 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>

Зауважте, що Методи вказуються індивідуально, а не використовуються *. Це тому, що при використанні виникає помилка *.

Ви також можете ввімкнути 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.

Щоб вирішити це, все, що вам потрібно зробити, це відправити порожню відповідь назад. Ви можете зробити це всередині своїх дій, або ви можете зробити це в усьому світі так:

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

Ця додаткова перевірка була додана, щоб гарантувати, що старі APIs, призначені лише для прийому GETта POSTзапитів, не будуть використані. Уявіть, що надіслати DELETEзапит APIпризначеному дизайну, коли цього дієслова не існувало. Результат непередбачуваний і результати можуть бути небезпечними .


4
Ваша відповідь мені допомогла. Я спробував усе, що міг, з рішеннями кодової бази. Я не спробував варіант web.config, поки не прочитав вашу відповідь. Це працювало єдине. Будь-яка ідея чому? Я використовую Web API 2 з OData. Все одно, дякую! :)
Феліпе Кореа

1
Для подальшого ознайомлення, необхідний для вас пакет NuGet - це "Microsoft.AspNet.WebApi.Cors".
BrainSlugs83

2
Я дотримувався всієї вашої відповіді, і у мене є два питання: Де слід звертатися до Application_BeginRequest ()? по-друге, у тому ж методі.
meJustAndrew

2
пам’ятайте, що інший порт # є іншим доменом, який може бути ґутчем. foo.com - інший домен, ніж foo.com:8080
RyBolt

2
Ти врятуєш мені життя;)
Paweł Groński

26

@ Відповідь Михай-Андрея Дінкулеску правильна, але для користі шукачів є також тонкий момент, який може спричинити цю помилку.

Додавання "/" в кінці вашої 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.


Дякую!! Це було корисно.
Анкіт Сахрават

23

Я дотримувався всіх вищезазначених кроків, зазначених Михайлом-Андрієм Дінкулеску .
Але в моєму випадку мені знадобився ще один крок, оскільки в режимі Web.Config http OPTIONS було вимкнено рядок нижче.

<remove name="OPTIONSVerbHandler" />

Я щойно вилучив його з Web.Config (просто прокоментуйте це як нижче), і Корс працює як шарм

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

9

Це може бути через встановлення нужних пакетів Cors.

Якщо ви зіткнулися з проблемою після встановлення та ебаляції cors з nuget, ви можете спробувати перевстановити веб-Api.

Від менеджера пакунків запустіть Update-Package Microsoft.AspNet.WebApi -reinstall


Це було саме для мене. Я встановив System.Web.Http.Cors, а потім видалив, що залишило WebApi у неправильній (оновленій) версії між 5.2.2 та 5.2.3
TaeKwonJoe

7

Спробуйте це, щоб переконатися, що ви правильно налаштували CORS:

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

Все ще не працює? Перевірте наявність заголовків HTTP.


щоб перевірити, чи працює його, також краще видалити підтримкуCredentials, а також він відключить cors в певних умовах
harishr

Найкраща відповідь, тому що я не хочу вмикати CORS для всього свого сайту, лише певні кінцеві точки. config.EnableCors()для цього також потрібен.
Csaba Toth

4

Щоб будь-який протокол CORS працював, вам потрібно мати метод OPTIONS на кожній кінцевій точці (або глобальний фільтр з цим методом), який повертає ці заголовки:

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

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


2

Я спіймаю наступний випадок про корсів. Можливо, комусь це стане в нагоді. Якщо ви додаєте функцію "WebDav Redirector" на свій сервер, запити PUT та DELETE не виконані.

Отже, вам потрібно буде видалити "WebDAVModule" зі свого сервера IIS:

  • Msgstr "У налаштуваннях модулів IIS зациклюйте WebDAVModule, якщо ваш веб-сервер має його, тоді видаліть його".

Або додати до конфігурації:

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


2

Я знаю, що приходжу до цього дуже пізно. Однак для кожного, хто шукає, я думав, що опублікую те, що НАРЕШТУ працює на мене. Я не стверджую, що це найкраще рішення - лише те, що воно спрацювало.

Наш сервіс WebApi використовує метод config.EnableCors (corsAttribute). Однак, навіть при цьому, він все одно не зможе виконати запити перед польотом. @ Відповідь Михай-Андрея Дінкулеску дала мені зрозумілу інформацію. Перш за все, я додав його Application_BeginRequest () код, щоб очистити запити параметрів. Це СТАЛО не працювало для мене. Проблема полягає в тому, що WebAPI досі не додавав жодного із очікуваних заголовків до запиту OPTIONS. Промивання його поодинці не спрацювало - але це дало мені ідею. Я додав власні заголовки, які в іншому випадку будуть додані через web.config у відповідь на запит OPTIONS. Ось мій код:

protected void Application_BeginRequest()
{
  if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
  {
    Response.Headers.Add("Access-Control-Allow-Origin", "https://localhost:44343");
    Response.Headers.Add("Access-Control-Allow-Headers",
      "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
    Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
    Response.Headers.Add("Access-Control-Allow-Credentials", "true");
    Response.Flush();
  }
}

Очевидно, це стосується лише запитів OPTIONS. Усі інші дієслова обробляються за допомогою конфігурації CORS. Якщо є кращий підхід до цього, я все вухо. Мені це здається шахрайством, і я вважаю за краще, якщо заголовки додаватимуться автоматично, але саме це, нарешті, спрацювало і дозволило мені рухатись далі.


1

@ Відповідь Міхай-Андрея Дінкулеску працювала на мене, наприклад:

  • Додавання <httpProtocol>в web.config , в <system.webServer>розділі
  • Повернення порожньої відповіді на 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) {


0

Якщо у вас є вузли безпеки \ requestФільтр у вашому web.config:

<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

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

у файлі 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

Я знаю, що люди, мабуть, спочатку вважають це дуже очевидним, але дійсно думають над цим. Це часто може статися, якщо ви зробили щось не так.

Наприклад, у мене виникла ця проблема, оскільки я не додав хост-запис у свій файл хостів. Справжньою проблемою було дозвіл DNS. Або я просто помилився з базовою URL-адресою.

Іноді я отримую цю помилку, якщо маркер ідентичності надходив з одного сервера, але я намагаюся використовувати його на іншому.

Іноді ви отримаєте цю помилку, якщо помилилися ресурсом.

Ви можете отримати це, якщо занадто пізно покласти проміжне програмне забезпечення CORS у ланцюг.


0

Уникайте ввімкнення кількох місць CORS, як, наприклад, WebApiCOnfig.cs, методу GrantResourceOwnerCredentials у постачальника та атрибута заголовка контролера тощо. Нижче наведено список, що також спричиняє контроль доступу дозволити вихід

  1. Веб має надійну взаємодію з БД, який ви використовували.
  2. AWS Cloud Якщо VPC веб-API та DB відрізняються.

Нижче коду більш ніж достатньо, щоб виправити походження контролю доступу. // Переконайтеся, що app.UseCors має бути вгорі рядка коду конфігурації.

   public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
            //All other configurations
        }
    }

Це уповільнило мою проблему.


0

Ця проблема виникає при спробі доступу з іншого домену або іншого порту.

Якщо ви використовуєте Visual Studio, перейдіть до Інструменти> NuGet Package Manager> Package Manager Console. Там ви повинні встановити пакет NuGet Microsoft.AspNet.WebApi.Cors

Install-Package Microsoft.AspNet.WebApi.Cors

Потім у PROJECT> App_Start> WebApiConfig увімкніть CORS

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        
        //Enable CORS. Note that the domain doesn't have / in the end.
        config.EnableCors(new EnableCorsAttribute("https://tiagoperes.eu",headers:"*",methods:"*"));

        ....

    }
}

Після успішного встановлення побудуйте рішення і цього повинно вистачити

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.