MVC web api: заголовок "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;
}
}
}
Ответы
Ответ 1
Вам нужно включить 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>
Обратите внимание, что все методы задаются индивидуально, вместо использования *
. Это связано с тем, что при использовании *
появляется ошибка.
Вы также можете включить 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
, когда этот глагол не существовал. Результат непредсказуем, и результаты могут быть опасными.
Ответ 2
@Ответ Михая-Андрея Динкулеску правильный, но в интересах поисковиков есть также тонкая точка, которая может вызвать эту ошибку.
Добавление '/' в конец вашего 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.
Ответ 3
Я следил за всеми шагами, указанными Михаем-Андреем Динкулеску.
Но в моем случае мне понадобился шаг еще 1, потому что http OPTIONS был отключен в Web.Config по строке ниже.
<remove name="OPTIONSVerbHandler" />
Я просто удалил его из Web.Config(просто прокомментируйте его, как показано ниже), и Cors работает как шарм
<handlers>
<!-- remove name="OPTIONSVerbHandler" / -->
</handlers>
Ответ 4
Возможно, это связано с установкой пакетов Cors nuget.
Если вы столкнулись с проблемой после установки и установки кода из nuget, вы можете попробовать переустановить веб-Api.
В диспетчере пакетов запустите Update-Package Microsoft.AspNet.WebApi -reinstall
Ответ 5
Попробуйте это, чтобы убедиться, что вы правильно настроили CORS:
[EnableCors(origins: "*", headers: "*", methods: "*")]
Все еще не работает? Проверьте наличие заголовков HTTP.
Ответ 6
Чтобы протокол CORS работал, вам необходимо иметь метод OPTIONS на каждой конечной точке (или глобальный фильтр с помощью этого метода), который будет возвращать эти заголовки:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: content-type
Причина в том, что браузер сначала отправит запрос OPTIONS для "проверки" вашего сервера и просмотра разрешений
Ответ 7
@Ответ Михай-Андрея Динкулеску работал у меня, например:
- Добавление
<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) {
Ответ 8
Please make this change in webapi.config file to enable cors and avoid the below error
asp.net webapi Ответ на запрос предварительной проверки не проходит проверку контроля доступа: в запрашиваемом ресурсе отсутствует заголовок "Access-Control-Allow-Origin".
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
//... existing values in register seection
}
}
Ответ 9
Я поймал следующий случай о корсах. Может быть, это кому-нибудь пригодится. Если вы добавляете функцию "WebDav Redirector" на свой сервер, запросы PUT и DELETE не выполняются.
Итак, вам нужно удалить "WebDAVModule" с вашего сервера IIS:
- "В конфигурации модулей IIS зафиксируйте модуль WebDAVModule, если он есть на вашем веб-сервере, а затем удалите его".
Или добавьте в свой конфиг:
<system.webServer>
<modules>
<remove name="WebDAVModule"/>
</modules>
<handlers>
<remove name="WebDAV" />
...
</handlers>
Ответ 10
Если в вашем файле 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" />
Ответ 11
Я перепробовал все, что мог найти в сети, включая методы, которые были даны в этом ответе. После почти полной попытки решить проблему в течение целого дня я нашел решение, которое сработало для меня, как шарм.
в файле 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");
}
}'
Ответ 12
Я знаю, что приду к этому очень поздно. Тем не менее, для всех, кто искал, я думал, что опубликую то, что НАКОНЕЦ работает для меня. Я не претендую на это лучшее решение - только то, что это сработало.
Наш сервис 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. Если есть лучший подход к этому, я все уши. Мне это кажется читом, и я бы предпочел, чтобы заголовки добавлялись автоматически, но это то, что в итоге сработало и позволило мне двигаться дальше.