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

  1. nginx обработал первый try_files параметр $uri (который равен /login), пытается проверить существование /home/projects/insights/vue/dist/login файла и терпит неудачу;

  2. nginx обработал второй try_files параметр $uri/, пытается проверить /home/projects/insights/vue/dist/login/ существование каталога и терпит неудачу;

  3. nginx обработал третий try_files параметр /home/projects/myproject/vue/dist/index.html, пытается проверить /home/projects/insights/vue/dist/home/projects/myproject/vue/dist/index.html существование файла и терпит неудачу;

  4. 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/ {}
}
Вернуться на верх