Управление местоположением NginX с настройкой Django&Vue.js
У меня есть Django backend и Vue.js frontend, обслуживаемые одной машиной. Я хочу, чтобы определенный путь был направлен к API django и панели администратора, а остальные пути должны загружать Vue index.html и передаваться в Vue router. Моя проблема в том, что хотя базовый путь передается в Vue.js, и выбранный мной путь действительно проходит через Django, любой другой путь приводит к 404, что означает, что если я захочу вернуться к пути, сгенерированному через Vue router, это невозможно сделать.
Я решил, что проблема должна быть где-то в конфигурационном файле NginX:
# the upstream component nginx needs to connect to
upstream myproject {
server unix:///tmp/myproject .sock;
}
server {
listen 80;
listen [::]:80;
server_name serverurl.com;
return 301 https://serverurl.com$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /home/projects/myproject/ssl/ANY.serverurl.com.crt;
ssl_certificate_key /home/projects/myproject/ssl/ANY.serverurl.com.key;
server_name serverurl.com www.serverurl.com;
access_log /home/projects/myproject/logs/nginx_access.log;
error_log /home/projects/myproject/logs/nginx_error.log;
location / {
root /home/projects/insights/vue/dist;
try_files $uri $uri/ /home/projects/myproject/vue/dist/index.html =404;
}
location /backend/ {
include /etc/nginx/uwsgi_params;
uwsgi_pass myproject;
}
location /static/ {
alias /home/projects/myproject/static/;
}
location /media/ {
alias /home/projects/myproject/media/;
}
}
Так путь "/" приводит к корректному рендерингу Vue index.html
И "/backend/" правильно загружает урлы django
Но, например, если пользователь пытается получить доступ к "/" и не вошел в систему, он будет перенаправлен на "/login" маршрутизатором Vue, который работает нормально, и страница входа работает правильно, а пользователь перенаправляется обратно на "/". Но, если пользователь пытается получить доступ к "/login" напрямую, или к любому другому маршруту, такому как "/options", "/profile" и т.д.. Я пытался использовать какой-то regex, но, к сожалению, не смог разобраться, и в результате получал бесконечный редирект на "/index.html/index.html...", пока браузер не блокировал редирект.
Вот моя попытка: Я добавил это место в конец config:
location ~* ^/(.*) {
index /home/projects/myproject/vue/dist/index.html;
}
Посмотрим на вашу директиву try_files:
try_files $uri $uri/ /home/projects/myproject/vue/dist/index.html =404;
Что же произошло, когда пользователь пытается получить прямой доступ к URI /login?
nginx обработал первый
try_filesпараметр$uri(который равен/login), пытается проверить существование/home/projects/insights/vue/dist/loginфайла и терпит неудачу;nginx обработал второй
try_filesпараметр$uri/, пытается проверить/home/projects/insights/vue/dist/login/существование каталога и терпит неудачу;nginx обработал третий
try_filesпараметр/home/projects/myproject/vue/dist/index.html, пытается проверить/home/projects/insights/vue/dist/home/projects/myproject/vue/dist/index.htmlсуществование файла и терпит неудачу;nginx возвращает код HTTP 404 Not Found.
Как сказано в документации, последний параметр директивы try_files может быть
- новый URI;
- код ошибки HTTP:
=code; - ID именованного места:
@location_name.
Вам нужно обрабатывать все запросы к несуществующим файлам с помощью вашего приложения Vue index.html, поэтому измените вашу директиву try_files, чтобы использовать /index.html в качестве нового URI, если все остальные проверки не дали результата:
try_files $uri $uri/ /index.html;
(и я не уверен, что вам вообще нужна эта часть $uri/, возможно, достаточно try_files $uri /index.html;).
Дополнительно, я рекомендую вам использовать root /home/projects/myproject вместо директив alias /home/projects/myproject/static/ и alias /home/projects/myproject/media/. Как сказано в документации к директиве alias:
Когда местоположение совпадает с последней частью значения директивы:
location /images/ { alias /data/w3/images/; }вместо нее лучше использовать корневую директиву:
location /images/ { root /data/w3; }
Таким образом, вы можете упростить конфигурацию до
server {
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /home/projects/myproject/ssl/ANY.serverurl.com.crt;
ssl_certificate_key /home/projects/myproject/ssl/ANY.serverurl.com.key;
server_name serverurl.com www.serverurl.com;
access_log /home/projects/myproject/logs/nginx_access.log;
error_log /home/projects/myproject/logs/nginx_error.log;
root /home/projects/myproject;
location / {
root /home/projects/insights/vue/dist;
try_files $uri /index.html;
}
location /backend/ {
include /etc/nginx/uwsgi_params;
uwsgi_pass myproject;
}
location /static/ {}
location /media/ {}
}