一、问题
1.1 问题概述
将React应用打包后,部署到服务器上,在非首页的地方使用浏览器自带的刷新功能,页面刷新失败,显示404;
如果你的问题和我类似,可以往下看~
1.2 问题详细描述
在项目开发完成后,将应用通过 npm run build 打包,之后将该包部署到服务器上并通过Nginx将地址指向了服务器的包路径,Nginx的配置如下:
server {
listen 443 ssl;
server_name xxxxx.xxxxxxx.com;
# access_log /var/log/nginx/access.log main;
# error_log /var/log/nginx/error.log;
ssl_certificate /etc/nginx/cert/xxxxx.xxxxxx.xxx.pem; #填写解压的pem文件
ssl_certificate_key /etc/nginx/cert/xxxxx.xxxxxx.xxx.key; #填写解压的key文件
# ssl on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 50m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root /usr/share/nginx/html;
}
}
此时,打开域名网页可正常浏览,也可以正常登录,但在登录后的页面使用浏览器的刷新功能,网页会报404,显示缺少资源;
二、解决
2.1 修改Nginx配置
将Nginx的配置改成如下:
server {
listen 443 ssl;
server_name xxxxx.xxxxxxx.com;
# access_log /var/log/nginx/access.log main;
# error_log /var/log/nginx/error.log;
ssl_certificate /etc/nginx/cert/xxxxx.xxxxxx.xxx.pem; #填写解压的pem文件
ssl_certificate_key /etc/nginx/cert/xxxxx.xxxxxx.xxx.key; #填写解压的key文件
# ssl on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 50m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
try_files $uri $uri/ /index.html;
root /usr/share/nginx/html;
}
}
和之前相比,加了这一行
try_files $uri $uri/ /index.html;
使用了try_files指令,意思是检查url是否存在,如果不存在则一直往后找,这里就相当于,先检查了$uri是否存在,如果不存在再检查$uri/是否存在,如果都不存在则定向到/index.html上;
2.2 造成的原因
造成404的根本原因是在服务器上找不到该路由地址,我们知道浏览器上的地址和服务器上的文件是一一对应的,换句话说,在浏览器上我们输入了xxx.com/a,那么当访问传到nginx里的时候,nginx就会去找这个/a对应的是什么,如果是静态文件,那么就将这个静态文件发送到浏览器,并显示在界面上
但我们知道,React和Vue之类的都是单页应用,整个站点上所有的内容都是集中在index.html里的,路由也是纯前端路由,浏览器地址发生改变时并不需要服务器去做相对应的操作,换句话说,也就是路由和服务端无关,并且nginx上也没有对应静态文件,因此访问不存在的路由服务器自然就会反馈前端404找不到资源。