gin + vue 前后端分离项目必须分开构建、分开托管,并明确跨域或反向代理边界;混放 dist 到 gin static 目录会破坏分离原则,导致路由 404、hmr 失效、cors 冲突等问题。

直接上结论:Gin + Vue 前后端分离项目部署,**必须分开构建、分开托管、明确跨域或反向代理边界**;混放 dist 文件到 Gin 静态目录看似简单,实则破坏分离原则,且在生产环境会引发路由 404、HMR 失效、CORS 冲突等连锁问题。
Vue 构建产物不能直接扔进 Gin 的 static 目录
这是最常踩的坑。有人把 vite build 后的 dist/ 整个拷进 Gin 项目,再用 router.StaticFS("/static", http.Dir("./dist")) 暴露,结果访问 /login 刷新就 404——因为 Vue Router 是 history 模式,依赖前端路由接管所有路径,而 Gin 并未配置 fallback。
- 正确做法是:Vue 构建后由独立 HTTP 服务(如 Nginx、Caddy)托管
dist/index.html,并配置try_files $uri $uri/ /index.html;回退规则 - 若强行用 Gin 托管前端,必须手动实现 SPA fallback:用
router.NoRoute拦截所有非 API 路径,统一返回dist/index.html,但此时需确保/api/等前缀严格与后端 API 区分 - Gin 的
StaticFS不处理 HTML 文件的 MIME 类型协商,容易导致 JS/CSS 加载失败,尤其在 IE 或旧版 Edge 中
Gin 后端必须显式处理 CORS 或交由反向代理统一管控
开发时前端跑 http://localhost:5173,后端跑 http://localhost:8080,浏览器直接拦截请求,报错 Access to fetch at 'http://localhost:8080/api/login' from origin 'http://localhost:5173' has been blocked by CORS policy。
- 开发阶段可用
github.com/rs/cors中间件快速启用:c := cors.New(cors.Config{AllowOrigins: []string{"http://localhost:5173"}}),但上线前必须收紧AllowOrigins,禁用* - 生产环境更推荐由 Nginx 统一做反向代理:前端域名
app.example.com,后端 API 映射为app.example.com/api/,彻底规避跨域问题 - 注意
OPTIONS预检请求可能被 Gin 默认路由忽略,需确认中间件注册顺序——cors必须在router.Use()中靠前注册
Docker Compose 部署时,Vue 和 Gin 容器不能共用一个网络别名
常见错误是在 docker-compose.yml 里给 Vue 容器设 networks: default,又让 Gin 容器也连 default,然后前端 Axios 请求写成 http://gin:8080/api——这在容器内可行,但浏览器运行的是宿主机上的 Vue,根本无法解析 gin 这个 hostname。
- 浏览器永远通过公网/局域网 IP 或域名访问,所以 Axios 的
baseURL必须填真实可访问地址,例如https://api.example.com或http://192.168.1.100:8080 - Docker Compose 中只需保证 Gin 容器
ports:正确暴露(如"8080:8080"),前端容器无需暴露端口,只负责构建静态文件供 Nginx 挂载 - 若用多阶段构建,Vue 的
Dockerfile应基于node:alpine构建,最后 COPYdist/到 Nginx 镜像,而非启动一个 Node server
真正麻烦的不是部署命令本身,而是前后端对“请求来源”和“资源路径”的认知错位:Vue 编译时的 base、publicPath、Axios 的 baseURL、Nginx 的 location 块、Gin 的路由前缀,这五处必须严格对齐,漏掉任意一个,就会出现白屏、接口 404 或静态资源加载失败。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











