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/