publicPath 与 Nginx 的 alias 或 root 配置必须严格匹配,否则导致静态资源 404;正确做法是使用带尾斜杠的 location 和 alias,并统一设置 Vue Router base 与 publicPath 一致。

publicPath 和 Nginx root/alias 不匹配导致静态资源 404
Vue 或 React 构建时设了 publicPath: '/myapp/',但 Nginx 的 root 指向了网站根目录(如 /usr/share/nginx/html),而没把构建产物放进去——结果浏览器请求 /myapp/static/js/app.abc.js,Nginx 却去查 /usr/share/nginx/html/myapp/static/js/app.abc.js,文件根本不存在,返回 404。
关键不是“有没有配 publicPath”,而是它和 Nginx 实际服务路径是否对得上。常见错误包括:
- 前端设了
publicPath: '/myapp/',但 dist 文件夹直接扔在/html/下,没建/html/myapp/子目录 - 用了
alias但末尾漏了斜杠,比如写成alias /var/www/myapp而不是alias /var/www/myapp/,导致路径拼接错位 - 误用
root在子路径 location 中(如location /myapp/ { root /var/www; }),这种写法实际会拼出/var/www/myapp/myapp/...,多了一层
用 alias 配置子路径部署最稳妥
alias 是专为子路径设计的,它会**完全替换匹配的 location 前缀**,避免路径叠加。比如请求 /myapp/css/app.css,location /myapp/ { alias /var/www/dist/; } 会让 Nginx 去找 /var/www/dist/css/app.css,而不是拼接。
正确写法必须注意三点:
-
location末尾带斜杠:location /myapp/ { ... }(否则/myapp和/myapp/会被当作不同路径) -
alias路径末尾也必须带斜杠:alias /var/www/dist/;(否则/myapp/css/会映射成/var/www/distcss/) -
try_files的 fallback 要写成/myapp/index.html,不能是/index.html,否则兜底会跳到根目录下
完整示例:
location /myapp/ {
alias /var/www/dist/;
index index.html;
try_files $uri $uri/ /myapp/index.html;
}
proxy_pass 代理 API 时路径前缀要主动剥离
如果后端接口也加了统一前缀(比如 Spring Boot 的 server.servlet.context-path=/myapp),那么前端请求 /myapp/api/login 时,Nginx 的 proxy_pass 必须去掉这个前缀再转发,否则后端收不到。
错误写法:proxy_pass http://backend;(会把完整路径 /myapp/api/login 转发过去)
正确写法:proxy_pass http://backend/;(末尾斜杠触发剥离)或显式重写:
location /myapp/api/ {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Host $host;
}
注意:proxy_pass 后带斜杠,Nginx 才会自动删掉匹配的 /myapp/api/ 前缀;不带斜杠则原样转发。
Vue Router base 必须与 publicPath 严格一致
vue-router 的 base 选项不是可选的“锦上添花”。当 publicPath 是 '/myapp/' 时,base 也必须设为 '/myapp/',否则路由跳转会生成 /myapp/myapp/system/user 这种双重前缀。
检查点很具体:
-
vue.config.js中publicPath: process.env.NODE_ENV === 'production' ? '/myapp/' : '/' -
router/index.js中new VueRouter({ base: '/myapp/', routes: [...] }) - Nginx 的
location、alias、try_files兜底路径全部使用/myapp/前缀
三者只要有一个漏掉或写错,就可能表现为:页面能打开,但点击路由跳转失败、刷新白屏、控制台报 Unexpected token '(说明 JS 请求返回了 HTML)。
Nginx 对路径的处理是纯字符串匹配,没有“智能推断”。publicPath、base、location、alias、proxy_pass 这五个地方的斜杠数量和位置,差一个就全崩。











