Tengo un backend de Django y un frontend de Vue.js atendidos por la misma máquina. Quiero que se dirija una ruta específica a la API de django y al panel de administración, mientras que el resto debe cargar Vue index.html y pasar al enrutador Vue. Mi problema es que, si bien la ruta base se pasa a Vue.js, y mi ruta seleccionada pasa a Django, cualquier otra ruta da como resultado 404, lo que significa que si quiero volver a visitar una ruta generada a través del enrutador Vue, es imposible hacerlo.
Supuse que el problema debía estar en algún lugar del archivo de configuración de 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/; } }Entonces, la ruta "/" da como resultado la representación correcta de Vue index.html
Y "/ backend /" carga correctamente las URL de django
Pero, por ejemplo, si el usuario intenta acceder a "/" y no ha iniciado sesión, el enrutador Vue lo redirigirá a "/login", que funciona bien y la página de inicio de sesión funciona correctamente, y el usuario será redirigido a "/". Pero, si el usuario intenta acceder a "/iniciar sesión" directamente, o cualquier otra ruta como "/opciones", "/perfil", etc. Intenté usar algún tipo de expresión regular, pero desafortunadamente no pude resolverlo. y resultó en una redirección infinita a "/index.html/index.html..." hasta que el navegador bloqueó la redirección.
Aquí está mi intento: agregué esta ubicación al final de la configuración:
location ~* ^/(.*) { index /home/projects/myproject/vue/dist/index.html; }Veamos su directiva try_files :
try_files $uri $uri/ /home/projects/myproject/vue/dist/index.html =404; Entonces, ¿qué sucedió aquí cuando su usuario intenta acceder directamente al URI /login ?
nginx procesó el primer parámetro try_files $uri (que es igual a /login ), intenta verificar la existencia del archivo /home/projects/insights/vue/dist/login y falla;
nginx procesó el segundo parámetro try_files $uri/ , intenta verificar la existencia del directorio /home/projects/insights/vue/dist/login/ y falla;
nginx procesó el tercer parámetro try_files /home/projects/myproject/vue/dist/index.html , intenta verificar la existencia del archivo /home/projects/insights/vue/dist/home/projects/myproject/vue/dist/index.html y falla;
nginx devuelve el código HTTP 404 No encontrado.
Como se indica en la documentación , el último parámetro de la directiva try_files puede ser
=code ;@location_name . Debe procesar todas las solicitudes de los archivos que no existen con su archivo index.html de la aplicación Vue, así que cambie su directiva try_files para usar /index.html como URI nuevo si todas las demás comprobaciones fallan:
try_files $uri $uri/ /index.html; (y no estoy seguro de que necesite esa parte $uri/ en absoluto, tal vez solo try_files $uri /index.html; sería suficiente).
Además, le recomiendo que use root /home/projects/myproject en lugar de las directivas alias /home/projects/myproject/static/ y alias /home/projects/myproject/media/ . Como dice la documentación de la directiva de alias :
Cuando la ubicación coincide con la última parte del valor de la directiva:
location /images/ { alias /data/w3/images/; }es mejor usar la directiva raíz en su lugar:
location /images/ { root /data/w3; }
De esa manera puede simplificar su configuración para
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/ {} }