Вопрос или проблема
Я создал прототип системы.
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-запросов. Используйте инструменты отладки для отслеживания сетевых запросов, чтобы лучше понять ситуацию.