我有一个Django后端和Vue.js前端由同一台机器服务。我想要一个特定的路径被定向到django API和管理面板,而其余的应该加载Vue index.html,并传递给Vue路由器。我的问题是,当基本路径被传递给Vue.js时,我选择的路径确实经过Django,任何其他路径都会导致404,这意味着如果我想重新访问通过Vue路由器生成的路径,这是不可能的。
我认为问题一定是在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
和"/后端/";正确加载django url
但是,例如,如果用户试图访问"/"并且没有登录,他将被重定向到"/login"通过Vue路由器,它工作正常,登录页面工作正常,用户被重定向回"/"但是,如果用户试图访问"/login"直接,或任何其他路由,如"/options", "/profile"等。我曾尝试使用某种正则表达式,但不幸的是无法找出它,并导致无限重定向到"/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;
那么,当您的用户试图直接访问/login
URI时,这里发生了什么?
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 code.
如文档所述,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匹配指令值的最后一部分时:
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/ {}
}