Angular2 для устранения проблемы с WebApi CORS
Я использую внешний интерфейс angular2 и бэкэнд WebApi.
Webapi включен с поддержкой CORS.
var cors = new EnableCorsAttribute("*", "*", "*");
GlobalConfiguration.Configuration.EnableCors(cors);
и он работает, потому что у меня разные сайты (jQuery/Javascript), которые используют этот api. Но с angular2 это не так. Я получаю следующее сообщение:
Ответ на запрос предполетной проверки не проходит проверку контроля доступа: на запрошенном ресурсе отсутствует заголовок "Access-Control-Allow-Origin".
Возможно, что-то связано с "предполетным запросом"?
Ответы
Ответ 1
У меня была такая же проблема в моем приложении Angular2.
Проблема, как уже было сказано, заключается в том, что перед каждым запросом, сделанным клиентом, на сервер отправляется запрос предварительной проверки.
Этот тип запроса имеет тип OPTIONS, и он обязан отправить сервер обратно ответный сигнал перед полетом со статусом 200 и заголовками, установленными для приема запросов от этого клиента.
Это мое решение (с выражением):
// Domain you wish to allow
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'YOUR-CUSTOM-HEADERS-HERE');
// Set to true if you need the website to include cookies in requests
res.setHeader('Access-Control-Allow-Credentials', true);
// Check if preflight request
if (req.method === 'OPTIONS') {
res.status(200);
res.end();
}
else {
// Pass to next layer of middleware
next();
}
Как вы можете видеть, я устанавливаю заголовки, а затем выбираю, если тип запроса - OPTIONS. В этом случае я отправляю статус 200 и завершаю ответ.
Таким образом, клиент будет авторизован, и вы также сможете настроить свои собственные заголовки во всех запросах.
Ответ 2
Ваше сообщение об ошибке сообщает, что в ответе вашего вызова нет Access-Control-Allow-Origin
. Это необходимо для включения CORS для этого запроса. Это не связано с Angular2.
Это инициируется на стороне клиента добавлением заголовка Origin
в запросе. У вас есть этот заголовок в вашем запросе? Используете ли вы предварительно запрограммированные запросы в других приложениях. Напоминаем:
- Простые запросы. Этот вариант использования применяется, если мы используем методы HTTP GET, HEAD и POST. В случае методов POST поддерживаются только типы контента со следующими значениями:
text/plain
, application/x-www-form-urlencoded
и multipart/form-data
.
- Предварительно запрошенные запросы. Когда случай использования "простых запросов" не применяется, выполняется первый запрос (с помощью метода HTTP OPTIONS), чтобы проверить, что можно сделать в контексте междоменных запросов.
Возможно, запросы OPTIONS неправильно обрабатываются на стороне сервера (не возвращать правильные заголовки,...).
Что было бы интересно, так это рассказать нам, по каким запросам возникает ошибка: ОПЦИИ один или целевой запрос. Вы можете посмотреть вкладку Сеть в DevTools...
Подробнее о том, как работает CORS:
Надеюсь, это поможет вам,
Thierry
Ответ 3
Есть ли у вас какие-либо параметры в вашем файле web.config для cors? например, <add name="Access-Control-Allow-Origin" value="*"/>
Если да, не забудьте удалить это и управлять кодом через код.
Ответ здесь поможет вам.
Ответ 4
Я знаю, что вопрос не запрашивает PHP-код. Я попал сюда из-за всей этой предвыборной кампании и Angular2. Когда я посмотрел на Маттео, я понял, почему запрос на мой сервер возвращается с 401. Это потому, что в предполетном браузере не отправляется токен авторизации, и поэтому сервер возвращается с 401, и браузер считает, что CORS не разрешено, Помните, что приведенный ниже код должен использоваться только на сервере разработки, если вы не знаете, что делаете.
В PHP вы можете сделать это:
if (strtolower($_SERVER['REQUEST_METHOD']) === 'options') {
header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Range, Content-Disposition, Content-Type, Authorization');
header('Access-Control-Allow-Credentials: true');
echo 'Allowed';
exit;
}
ИЛИ Nginx
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
Помните, какие другие заголовки вы отправляете на сервер, вы должны быть добавлены в список Access-Control-Allow-Headers.
Ответ 5
Я работаю с Angular 2 для front-end и nodeJS (Expressjs) для API
Angular 2 работает под localhost: 3000, а express работает на localhost: 8000
Проблема возникает, когда localhost: 3000 пытается вызвать URL-адрес с помощью метода POST... ExpressJS-сервер отклоняет вызов, потому что он поступает с другого сервера (или порта)
Чтобы решить проблему, вы должны сообщить node js, чтобы принимать вызовы с сервера localhost: 3000...
Вы можете найти библиотеку (CORS), чтобы избежать этой проблемы в этой ссылке:
Ответ 6
Вы можете добавить одно дополнение в свой браузер Firefox. Он будет работать в вашем браузере firefox, как прикол. Cors Everywhere решила мою проблему.
https://addons.mozilla.org/en-US/firefox/addon/cors-everywhere/