nginx с add_header ‘Access-Control-Allow-Origin’ ‘*’ но запрос всё равно заблокирован CORS

Вопрос или проблема

Я создал прототип системы.

Vue админ-клиент. ( localhost:8081 ). -->. [ Nginx ( публичный IP сервера). --> node.js ( localhost с портом 3000 ) ]

Был отправлен GET-запрос на /api/v1/capacha/code, но получена ошибка CORS. Как видно на первом изображении, сначала появилась ошибка XHR CORS, а затем предвходящий запрос 204 завершился успешно. Как видно на втором рисунке, предвходящий запрос OPTION возвращается с кодом 204.

вставьте описание изображения здесь

Вот мой первый вопрос: почему не происходит дальнейшего GET-запроса, когда предвходящий запрос успешно возвращается с кодом 204?

вставьте описание изображения здесь

На стороне сервера я посмотрел журнал доступа nginx и подтвердил, что на /api/v1/capacha/code есть только запросы OPTION.

[22/Сент/2024:03:14:07 +0800] "OPTIONS /api/v1/capacha/code HTTP/1.1" 204 0 "http://localhost:8081/" 
[22/Сент/2024:03:14:10 +0800] "OPTIONS /api/v1/capacha/code HTTP/1.1" 204 0 "http://localhost:8081/" 
.....

Вот моя конфигурация nginx

 server {

        listen 80 default_server;
        listen [::]:80 default_server;
       # Конфигурация сервера по умолчанию
         server_name http://app.myhost.com;
         location / {

              root /opt/web; try_files $uri /index.html;

         }
      location /api {
         # Добавить заголовки CORS
         add_header 'Access-Control-Allow-Origin' '*' всегда;
         add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' всегда;
         add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' всегда;
         add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' всегда;

         # Обработать предвходящие запросы OPTIONS
         if ($request_method = OPTIONS) {
              add_header 'Access-Control-Allow-Origin' '*';
              add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
              add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
              add_header 'Access-Control-Max-Age' 1728000;
              return 204;

          }

          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Proto $scheme;
          proxy_pass http://127.0.0.1:3000; # Конфигурация SSL
    }
 }

Очевидно, моя конфигурация nginx добавляет заголовок управления доступом и связанные заголовки, и код в секции ($request_method = OPTIONS) { } успешно возвращает 204. Но почему запрос все еще блокируется на уровне nginx?

Ответ или решение

Ваша проблема с CORS может быть связана с несколькими факторами, несмотря на то, что вы правильно настроили сервер Nginx для предобработки OPTIONS-запросов и добавления необходимых заголовков. Давайте рассмотрим возможные причины и решения.

1. Проверьте заголовки в ответе вашего сервера Node.js

Хотя Nginx добавляет необходимые заголовки для CORS, ваш сервер Node.js также должен это делать для всех ваших API-запросов, не только для OPTIONS. Убедитесь, что ваш сервер возвращает заголовок Access-Control-Allow-Origin в ответах на все запросы, включая GET-запросы. Например:

app.use((req, res, next) => {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
    res.header("Access-Control-Allow-Headers", "DNT, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Range");
    next();
});

2. Отладка заголовков ответа

Проверьте заголовки, которые возвращает ваш сервер Node.js при GET-запросе. Вы можете использовать инструменты, такие как Postman или встроенный инструмент разработчика в браузере (вкладка Network), чтобы увидеть, какие заголовки приходят.

3. Убедитесь, что GET-запрос действительно отправляется

Если ваш клиент не отправляет GET-запрос, возможно, есть проблема в коде Vue.js. Проверьте консоль на наличие ошибок или предупреждений. Убедитесь, что функция, которая должна отправлять GET-запрос, вызывается правильно.

4. Вопрос о порядке обработки запросов

Обратите внимание, что порядок обработки запросов важен. Убедитесь, что блоки конфигурации Nginx расположены корректно и не перекрываются с другими конфигурациями. Попробуйте переместить блок if ($request_method = OPTIONS) в начало блока location /api.

5. Обновление конфигурации Nginx

После внесения изменений в конфигурацию Nginx не забудьте перезапустить сервер:

sudo systemctl restart nginx

6. Пример полной конфигурации Nginx

Вот как мог бы выглядеть ваш блок конфигурации Nginx:

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name http://app.myhost.com;

    location / {
        root /opt/web;
        try_files $uri /index.html;
    }

    location /api {
        # Добавление заголовков CORS
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'DNT, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Range' always;
        add_header 'Access-Control-Expose-Headers' 'Content-Length, Content-Range' always;

        # Обработка предобработки OPTIONS запросов
        if ($request_method = OPTIONS) {
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
            add_header 'Access-Control-Allow-Headers' 'DNT, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Range';
            add_header 'Access-Control-Max-Age' 1728000;
            return 204;
        }

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host; 
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://127.0.0.1:3000;
    }
}

Заключение

Если после выполнения всех вышеперечисленных шагов проблема все еще сохраняется, рекомендую проверить логи вашего сервера Node.js на наличие ошибок и уточнить, какие заголовки возвращаются при выполнении GET-запросов. Используйте инструменты отладки для отслеживания сетевых запросов, чтобы лучше понять ситуацию.

Оцените материал
Добавить комментарий

Капча загружается...