Vue 项目部署与 404 问题解决
Vue 项目部署流程及 history 模式下刷新 404 问题的原因和解决方案
问题
Vue 项目如何部署到服务器?使用 history 模式时,刷新页面为什么会出现 404 错误?
解答
部署流程
前后端分离模式下,前端部署只需将构建产物上传到服务器的静态资源目录。
1. 构建项目
npm run build
2. 上传构建产物
# 使用 scp 上传到服务器
scp dist.zip user@host:/var/www/html
3. 配置 Nginx
server {
listen 80;
server_name www.xxx.com;
location / {
root /data/dist;
index index.html;
}
}
4. 重启 Nginx
# 检查配置
nginx -t
# 重启服务
nginx -s reload
404 问题原因
为什么 history 模式会出现 404?
Vue 是单页应用(SPA),构建后只生成一个 index.html 文件。当访问 www.xxx.com/login 并刷新时:
- 浏览器向服务器请求
/login路径 - Nginx 在服务器上找不到
login这个文件 - 返回 404 错误
本质原因:路由切换由前端 JS 控制,但刷新时会向服务器发起真实请求。
为什么 hash 模式没问题?
hash 模式的 URL 如 www.xxx.com/#/login,# 后面的内容不会发送到服务器。服务器只会收到 www.xxx.com 的请求,始终返回 index.html。
解决方案
1. 配置 Nginx 重定向
将所有请求重定向到 index.html,让前端路由接管:
server {
listen 80;
server_name www.xxx.com;
location / {
root /data/dist;
index index.html;
try_files $uri $uri/ /index.html;
}
}
2. 添加前端 404 页面
由于所有路径都返回 index.html,需要在前端处理无效路由:
const router = new VueRouter({
mode: 'history',
routes: [
// 其他路由...
{ path: '*', component: NotFoundComponent }
]
})
3. 重启 Nginx
nginx -s reload
关键点
- Vue 构建后只生成一个
index.html,所有路由由前端 JS 控制 - history 模式刷新会向服务器请求真实路径,找不到文件就返回 404
- hash 模式的
#后内容不会发送到服务器,所以不会出现 404 - 使用
try_files将所有请求重定向到index.html,交给前端路由处理 - 配置通配符路由
path: '*'处理前端的无效路径
目录