Vue项目配置二级域名访问,核心在于调整构建时的publicPath、路由的base路径,以及服务器端的转发规则,三者对齐后,静态资源、路由刷新和登录状态才能正常工作。
本文按实际踩坑顺序,从场景、配置、部署到排查,一步步拆解,希望对正被二级域名折腾的你有点帮助。
什么情况下需要给Vue项目配置二级域名?
不是所有项目都要上二级域名,但当你遇到下面这些场景时,配置就是刚需。
- 主域名放官网,Vue项目放在
app.example.com或者admin.example.com下,实现业务隔离。 - 不同环境共用一套代码,用二级域名区分测试、预发布、生产,比如
test.example.com和www.example.com。 - 项目里同时跑多个独立子系统,比如用户端和管理后台,各自部署,互不干扰。
二级域名的好处也直接:cookie作用域更干净,静态资源可以独立缓存,nginx配置模块化后更容易维护,不过代价是你要比单域名部署多考虑几层东西。
vue项目配置二级域名前要改哪些文件?
很多同学直接打包上传服务器,结果白屏、404、样式丢失,根因就是项目里的路径还写死为根路径,二级域名下,你的应用可能跑在https://二级域名.com/根路径,也可能跑在https://域名.com/二级目录/,但最常见的是前者,无论哪种,下面三个文件必须同步修改。
设置publicPath让静态资源走二级域名
Vue CLI项目修改vue.config.js,Vite项目修改vite.config.js,这里以Vite为例,Vue CLI思路一致。
// vite.config.js
export default defineConfig({
base: '/', // 二级域名根路径,如果是子目录就写 '/子目录/'
// 其他配置...
})
如果你遇到静态资源全部404,检查一下base是不是默认的相对路径,打包后的index.html里,link和script标签的src应该以开头,并且指向你的二级域名可访问的资源路径。
把路由base指向二级域名路径
Vue Router使用createWebHistory()时,默认base是,当你的应用部署在二级域名根路径,通常不需要额外改,但如果你用了createWebHistory('/admin/')这种写法,就必须和nginx里的location路径对齐。
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes
})
关键是import.meta.env.BASE_URL会读取Vite的base配置,二者必须一致,业内专家指出,多数二级域名部署问题都出在base和路由base不一致,导致刷新页面时路由匹配不到。
开发环境接口代理要跟着变
本地开发时,你以为二级域名只在线上生效,其实不是,如果你在vite.config.js里配了代理,代理的target要改为二级域名对应的后端地址,同时changeOrigin: true不能少,否则请求打到本地,还是会跨域。
server: {
proxy: {
'/api': {
target: 'https://api.example.com',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
}
vue部署二级域名后nginx怎么配?
服务器端是最后一道关卡,也是出错率最高的地方,Vue项目打包后是纯静态文件,nginx只需要做好静态文件托管、路由重写和接口转发。
基础server块和location配置
以部署在app.example.com为例,nginx配置如下:
server {
listen 80;
server_name app.example.com;
root /var/www/app/dist;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
try_files的作用是:当请求的路径不存在时,回退到index.html,让前端路由接管,没有这行配置,刷新二级域名下的/about页面就会直接404。
history路由刷新404的try_files处理
上面配置里的try_files $uri $uri/ /index.html;就是解决刷新404的关键,务必保持这个写法,如果项目放在子路径下,比如https://example.com/app/,那nginx的root和location都要做调整,这里不展开,但思路相同。
接口反向代理与跨域头
前端请求如果走相对路径/api,需要nginx把/api转发到后端服务,同时注意跨域,推荐把接口域名也设成二级域名,比如api.example.com,然后在前端配置里区分环境变量。
location /api/ {
proxy_pass https://backend.internal:8080/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
如果你的后端接口和前端不同域,还需要在响应头里加上Access-Control-Allow-Origin等CORS头,或者用nginx统一处理。
二级域名下登录状态丢失问题怎么解决?
这是二级域名配置里最隐蔽的坑,表面看起来页面都正常,但用户一登录,跳转回首页又变成未登录状态。
cookie作用域区别
浏览器处理cookie时,会把Domain属性匹配的cookie发送给对应域名,默认情况下,app.example.com的cookie只作用于app.example.com,不会影响www.example.com,如果你的前后端不在同一个二级域名下,后端设置的cookie无法被前端拿到。
解决办法有两种:
- 后端把cookie的
Domain设为.example.com,这样主域名和所有子域名都能共享cookie。 - 前端请求加上
withCredentials: true,这样跨域请求才会携带cookie。
在axios里这样写:
axios.defaults.withCredentials = true
后端还需要在响应头里明确返回Access-Control-Allow-Credentials: true,并且Access-Control-Allow-Origin不能是,必须是具体的源地址。
跨域接口携带凭据
如果你使用XHR或fetch请求二级域名接口,都要显式开启凭据。fetch的写法:
fetch('https://api.example.com/user', {
credentials: 'include'
})
不想每次手写,就封装到请求工具里统一处理。
vue项目二级域名访问404与白屏排查
打包配置和nginx都改完后,如果线上仍然异常,按照下面表格逐项排查,效率最高。
| 现象 | 常见原因 | 解决方案 |
|---|---|---|
| 首页白屏 | publicPath不对,静态资源加载失败 | 检查base配置,确认资源地址以开头 |
| 刷新子路由404 | nginx缺少try_files |
加上try_files $uri $uri/ /index.html; |
| 静态资源加载但不显示样式 | 资源路径指向了主域名根目录 | 检查base是否匹配nginx的location路径 |
| 登录后跳转丢失状态 | cookie作用域不匹配 | 后端设置Domain=.example.com,前端开启withCredentials |
| 接口请求404 | 代理或后端路径不对 | 查看nginx proxy_pass是否包含多余路径 |
多数情况下,白屏和404是同一类问题,根源都在路径不统一,你可以在浏览器控制台看Network面板,找到加载失败的资源,看它的URL前缀和实际文件存放位置一不一样,就能快速定位。
环境变量也要跟着域名走,打包前区分.env.development和.env.production,把VITE_API_BASE_URL指向对应的接口域名,避免每次手动改地址。
Vue二级域名适配的常见问题解答
vue项目配置二级域名后,环境变量里的接口地址要不要改?
要改,运行在不同二级域名下,接口地址大概率也不同,建议在.env.production里单独设置:
VITE_API_URL=https://api.example.com
然后在代码里统一读取import.meta.env.VITE_API_URL,打包时根据目标环境自动切换,不用改代码。
二级域名能不能和主域名使用同一个登录状态?
能,但前提是cookie的Domain要设为主域名的父级,比如.example.com,同时前端请求必须携带凭据,后端要允许跨域凭证,这样才能实现在app.example.com登录后,www.example.com也能识别同一用户。
vue3+vite配置二级域名和vue2+webpack有什么不同?
本质相同,区别只在于配置文件写法,Vue2+Vue CLI用publicPath,Vue3+Vite用base;路由部分都是createWebHistory,但Vite里用import.meta.env.BASE_URL更保险,nginx配置完全一样,不依赖前端框架,如果你从老项目迁移,重点把publicPath对应翻译成base即可。
二级域名适配这件事,只要抓住“路径一致”和“cookie域一致”两条主线,再配合nginx的简单配置,大部分问题都能在半小时内解决,下次再遇到白屏或404,先别急着改代码,用浏览器开发者工具看一眼请求路径,就能知道问题跑不出这几个原因。