一、出现问题的场景

项目是前后端分离,前端使用的vue,所以在部署前端时就使用nginx,vue打包就不多说了,一个命令的事(npm run build:prod),将生产的dist目录放在服务器上,在nginx的nginx.conf配置文件中配置一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
user root;
worker_processes 1

events {
worker_connections 1024;
}

http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;

server {
listen YYYY; //自己设置的端口号
server_name 192.168.XXX.XXX; //在黑窗口下ipconifg后出现的IPv4地址复制

location / {
root /home/ubuntu/myapp/ruoyi/ruoyi-ui/dist; # 路径改成自己的dist路径
index index.html index.htm;
}

location /prod-api/{
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:8080/; #设置监控后端启动的端口
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}

}

ok后,启动后台提供服务。我访问页面都没问题,但这时我习惯性刷新页面,结果直接显示nginx的404。

上述配置在通过浏览器访问时,进行 刷新 或 访问不存在 的路径时会直接跳到nginx的404页面。

二、解决方案

后来百度发现了解决方案:
修改nginx的nginx.conf配置文件中的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
server {
listen YYYY; //自己设置的端口号
server_name 192.168.XXX.XXX; //在黑窗口下ipconifg后出现的IPv4地址复制

location /{
root /home/ubuntu/myapp/ruoyi/ruoyi-ui/dist; # 路径改成自己的dist路径
index index.html index.htm;
try_files $uri $uri/ /index.html; //解决刷新页面变成404问题的代码
}

location /prod-api/{
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:8080/; #设置监控后端启动的端口
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}

解决代码

1
try_files $uri $uri/ /index.html;

在修改完nginx的配置文件后需要重启

1
2
3
cd /usr/local/nginx/sbin

./nginx -s reload

问题不仅要解决,还要知根知底,为什么添加了上面一行代码就解决了呢?

1
2
3
4
5
6
7
8
9
10
11
# 变量解释
try_files -尝试访问对应的资源,在第一个资源访问不到时,访问第二个资源,以次向后

$uri nginx地址变量,即为访问的地址

若访问url为 http://www.xxx.com/index.html 则 $uri 为 /index.html

$uri/ 表示一个目录,请求访问的目录,nginx try_files可自行判断访问目的的类型 是为文件还是目录

若访问url为 http://www.xxx.com/user/class/ 则 $uri/ 为 /user/class/

这里就不细说了,可以看看下面的文章

解释try_files $uri $uri/ /index.php$is_args$args;