测试环境
p>前端同学做完 Vue2 项目,部署到 Nginx 时是不是总碰到刷新 404、资源找不到、跨域失败这些问题?其实不是 Nginx 难,是配置细节和项目打包逻辑没对上,这篇从项目打包准备到Nginx 配置实操,再到常见坑点解决,一步步讲透,新手也能跟着搞定部署!
Vue2 项目打包前,这些准备工作不能少
很多部署问题,根源在打包阶段,得先把项目配置和路由模式理顺:
路由模式(Hash vs History)的选择
Vue Router 默认是 hash 模式(URL 带 ),这种模式下,打包后部署到 Nginx 基本不用额外配置,因为 后的路径不会传给服务器,但如果想去掉 用 history 模式,服务器必须配合处理路由转发——因为用户直接访问 /about
这类路径时,Nginx 如果没配置,会返回 404。
所以选 history 模式前,得确认:后端是否支持(或 Nginx 能否处理路由 fallback),然后在 router/index.js
里设置:
const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, // 对应 publicPath,打包时要一致 routes: [...] })
publicPath 与静态资源路径
Vue CLI 的 vue.config.js
里的 publicPath
,决定了打包后静态资源(js、css、img)的引用路径。
- 如果项目部署在域名根目录(如
https://xxx.com/
),publicPath
设为 即可。 - 如果部署在子路径(如
https://xxx.com/my-app/
),必须设为'/my-app/'
(注意末尾的斜杠),否则打包后资源会指向根目录,导致 404。
举个例子,子路径部署时 vue.config.js
配置:
module.exports = { publicPath: process.env.NODE_ENV === 'production' ? '/my-app/' : '/', outputDir: 'dist', // 打包输出目录 // ...其他配置 }
Axios 基础路径配置(跨域/接口路径)
如果前端请求后端接口,开发时用 proxy
代理(vue.config.js
的 devServer.proxy
),生产环境要改接口基础路径,可以用环境变量区分:
在 .env.production
文件里加:
VUE_APP_API_BASE = 'https://xxx.com/api' // 后端生产环境接口地址
然后在 Axios 封装里:
import axios from 'axios' const service = axios.create({ baseURL: process.env.VUE_APP_API_BASE, timeout: 5000 })
Nginx 配置核心步骤:把 Vue2 dist 丢进去就能跑?没那么简单
Nginx 的作用是“把静态文件吐给浏览器”+“处理路由/跨域/缓存”,核心是 nginx.conf
或自定义的 server 配置文件,步骤如下:
找到 Nginx 配置文件位置
不同系统位置不同:Linux 通常在 /etc/nginx/nginx.conf
,Mac 用 brew 安装的可能在 /usr/local/etc/nginx/nginx.conf
,Windows 在安装目录的 conf/nginx.conf
。
配置 server 块(以部署到根目录,history 模式为例)
打开配置文件,在 http
块里加一个 server
:
server { listen 80; # 监听端口,http 用 80,https 用 443 server_name your-domain.com; # 你的域名或 IP # 指向 Vue2 打包后的 dist 目录 root /usr/local/nginx/html/my-vue2-app/dist; index index.html index.htm; # 处理 history 模式的路由 fallback location / { try_files $uri $uri/ /index.html; # 尝试找文件→找目录→返回 index.html(让前端路由接管) } # 静态资源缓存(可选,优化性能) location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { expires 30d; # 缓存 30 天 add_header Cache-Control "public, max-age=2592000"; } # 错误页重定向(可选) error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } }
关键点解释:
root
:直接指向 dist 目录的绝对路径,要确保 Nginx 有访问权限(Linux 下注意用户组)。try_files
:history 模式必配!用户访问/about
时,Nginx 先找about
文件/目录,没有就返回index.html
,让 Vue Router 解析路由。location ~* \.(js|css|...)$
:对静态资源设置缓存,减少重复请求,但要注意,如果资源没加 hash(Vue CLI 默认的 chunkhash),更新后可能缓存不失效,所以结合打包时的 hash 命名更安全(Vue CLI 已自动处理)。
部署后必踩的 5 个坑,及解决方法
哪怕配置步骤对了,还是可能碰到奇奇怪怪的问题,这 5 个场景几乎人人踩过:
坑 1:刷新页面报 404(history 模式专属)
现象:首页能正常访问,点路由跳转也 ok,但刷新 /about
这类页面,Nginx 返回 404。
原因:Nginx 不认识前端路由,以为 /about
是真实文件/目录,找不到就返回 404。
解决:在 location /
里加 try_files $uri $uri/ /index.html;
(前面配置里已经写了,没加的话补上)。
坑 2:静态资源(js/css/img)加载 404
现象:控制台报 net::ERR_ABORTED 404
,资源路径不对。
原因分两种:
-
publicPath
配置错误:比如部署在子路径/my-app/
,但publicPath
设为 ,导致资源路径变成https://xxx.com/js/app.xxx.js
,实际应该是https://xxx.com/my-app/js/...
。
解决:修改vue.config.js
的publicPath
为'/my-app/'
,重新打包部署。 -
Nginx 的
root
或alias
用错:root
是“拼接路径”,root /usr/dist
,请求/js/app.js
会找/usr/dist/js/app.js
。alias
是“替换路径”,alias /my-app/ /usr/dist/
,请求/my-app/js/app.js
会找/usr/dist/js/app.js
。
如果项目部署在子路径,用alias
更稳妥,比如子路径部署时,server 配置改成:location /my-app/ { alias /usr/local/nginx/html/my-vue2-app/dist/; try_files $uri $uri/ /my-app/index.html; # 注意 index.html 的路径要对应 alias 后的位置 }
坑 3:跨域请求失败(生产环境)
开发时用 devServer.proxy
能解决跨域,但生产环境前端和后端域名不同,就会触发浏览器同源策略。
解决方法二选一:
-
后端设置 CORS 头(推荐):让后端在响应头加
Access-Control-Allow-Origin: *
(或指定前端域名)、Access-Control-Allow-Methods: GET,POST,...
等。 -
Nginx 反向代理(前端请求走 Nginx 转发,避免跨域):
比如前端请求/api
开头的接口,Nginx 把/api
转发到后端地址:location /api { proxy_pass https://backend-domain.com; # 后端真实地址 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; # 其他代理配置... }
这样前端 Axios 的 baseURL 设为
'/api'
,请求就会被 Nginx 代理到后端,绕开跨域。
坑 4:部署后页面样式错乱、JS 报错(缓存问题)
现象:明明更新了代码,部署后还是旧样式/功能,强制刷新也没用。
原因:Nginx 或浏览器缓存了旧的静态资源。
解决组合拳:
-
打包时让资源文件名带 hash:Vue CLI 默认开启,打包后文件是
app.xxx.js
、chunk-xxx.css
,这样每次构建 hash 不同,强制浏览器重新请求。 -
Nginx 配置缓存策略时,对带 hash 的资源设置长缓存,对
index.html
设置不缓存:# 对 index.html 禁用缓存(因为路由变化靠它) location = /index.html { add_header Cache-Control "no-cache, no-store, must-revalidate"; add_header Pragma no-cache; add_header Expires 0; } # 对带 hash 的静态资源设置长缓存 location ~* \.(js|css|png|jpg|jpeg|gif|ico)(\?.*)?$ { expires 30d; add_header Cache-Control "public, max-age=2592000"; }
-
强制刷新:用户端按
Ctrl+F5
(强制清除缓存重新请求),或部署时加版本号参数(index.html?version=202401
)。
坑 5:Nginx 启动失败或配置不生效
现象:执行 nginx -s reload
没反应,或访问时显示 Nginx 默认页面。
排查步骤:
-
检查配置语法:执行
nginx -t
,看是否报configuration file /etc/nginx/nginx.conf test is successful
,有错误就根据提示改。 -
检查端口占用:
netstat -tunlp | grep 80
(Linux),看 80 端口是否被其他程序占用,Apache。 -
检查文件路径:
root
或alias
配置的路径是否存在,文件权限是否给 Nginx 用户(Linux 下 Nginx 默认用户是www-data
或nginx
,要确保它能读 dist 目录)。
进阶:Nginx 性能优化+多环境部署技巧
搞定基础部署后,还能折腾这些进阶操作:
开启 Gzip 压缩,减少传输体积
Nginx 支持对静态资源(js、css、html)压缩后再发给浏览器,能省 50%+ 流量,配置如下:
http { gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; gzip_min_length 1k; # 小于 1k 不压缩 gzip_comp_level 5; # 压缩级别 1-9,5 是平衡 gzip_buffers 4 16k; gzip_http_version 1.1; gzip_vary on; # 告诉代理服务器缓存压缩和未压缩版本 }
多环境部署:测试、预发、生产
如果想一套 Nginx 同时部署多个环境(比如测试环境用 test.xxx.com
,生产用 xxx.com
),可以配置多个 server
块:
listen 80; server_name test.xxx.com; root /usr/nginx/dist-test; # ...其他配置(try_files、缓存等) } # 生产环境 server { listen 80; server_name xxx.com; root /usr/nginx/dist-prod; # ...其他配置 }
打包时,通过 --mode
指定环境:
# 测试环境打包 vue-cli-service build --mode test # 生产环境打包 vue-cli-service build --mode production
然后把不同环境的 dist 包放到对应的 Nginx 目录即可。
HTTPS 配置:让站点更安全
现在主流站点都用 HTTPS,Nginx 配置步骤:
-
申请 SSL 证书(Let’s Encrypt 免费证书或付费证书),得到
cert.pem
和privkey.pem
文件。 -
配置 Nginx 的
server
块支持 HTTPS:server { listen 443 ssl; server_name xxx.com; ssl_certificate /path/to/cert.pem; # 证书路径 ssl_certificate_key /path/to/privkey.pem; # 私钥路径 ssl_protocols TLSv1.2 TLSv1.3; # 安全协议 ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5; # 加密套件 # 强制 HTTP 跳转到 HTTPS location / { return 301 https://$host$request_uri; } # 其他配置(root、try_files 等)... }
-
重启 Nginx:
nginx -s reload
,然后访问https://xxx.com
验证。
部署流程再梳理
最后把整个部署链路理清楚,避免遗漏步骤:
-
确认 Vue2 项目配置:
- 路由模式(history 需后端/Nginx 配合)
- publicPath 与部署路径一致
- Axios 基础路径区分环境
-
打包项目:
npm run build
,得到 dist 目录。 -
上传 dist 到 Nginx 的对应目录(如
/usr/local/nginx/html/my-app/
)。 -
配置 Nginx 的 server 块:
- 正确设置 root/alias、try_files(history 模式)
- 处理静态资源缓存、跨域、Gzip 等
-
测试验证:
- 访问首页,点击路由跳转,刷新页面→检查是否 404
- 打开控制台,检查资源加载、接口请求是否正常
- 测试不同环境(如测试、生产)的访问逻辑
Vue2+Nginx 部署不难,核心是“前端路由和后端静态服务的配合”+“配置细节的严谨性”,碰到问题时,先看控制台报错(资源路径?接口跨域?),再对应 Nginx 配置和项目打包逻辑,基本都能定位,多试几次,部署就变成 routine 操作啦~
(如果还有特殊场景,Docker 里部署 Nginx+Vue2,或者结合 Jenkins 自动部署,评论区喊我,下次展开讲!)
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。