Управление местоположением 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/ {}
}