embed嵌入前端资源,配置前端路由的代码如下
func StartHttpService(port string, assetsFs embed.FS) error {
//r := gin.Default()
gin.SetMode(gin.ReleaseMode)
r := gin.New()
r.Use(CORSMiddleware())
// 静态文件服务
dist, err := fs.Sub(assetsFs, "assets/dist")
if err != nil {
return fmt.Errorf("无法加载静态文件: %v", err)
}
r.StaticFS("/", http.FS(dist))
// API路由
r.Any("/api/service", handler.ServiceControlsHandler)
r.Any("/api/service/config", handler.ServiceConfigsHandler)
// 处理前端路由
r.NoRoute(func(c *gin.Context) {
c.FileFromFS("index.html", http.FS(dist))
})
go func() {
common.Logger.Info(fmt.Sprintf("Web服务正在启动,监听端口 :%s", port))
err := r.Run(":" + port)
if err != nil {
common.Logger.Error(fmt.Sprintf("http service start error: %v", err))
} else {
common.Logger.Info("http service start success")
}
}()
return nil
}
运行后报错
panic: '/api/service' in new path '/api/service' conflicts with existing wildcard '/*filepath' in existing prefix '/*filepath'
问题解决步骤:
- 分析错误原因
在Gin框架中,路由注册顺序和路径模式会导致冲突。当前代码在注册/api/service
路由时,与之前注册的通配符路由/*filepath
发生冲突。Gin不允许在同一个路径前缀上注册多个处理函数。 - 确定解决方案
为了解决路由冲突问题,需要调整前端路由的基路径:
- 将根路径
/
重定向到/admin
- 修改前端构建配置,将静态资源的基路径设为
/admin
- 修改Golang代码
在StartHttpService
函数中:
- 添加根路径重定向:
```go
r.GET("/", func(c *gin.Context) {
c.Redirect(http.StatusMovedPermanently, "admin/")
})
- 修改静态文件服务路径:
r.StaticFS("/admin", http.FS(dist))
- 修改前端配置
在vite.config.js
中添加base配置:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
base: '/admin/',
})
- 重新构建前端资源
执行npm run build
生成新的静态资源,并确保生成的文件与/admin
路径匹配。 - 验证生效
重新启动服务后:
- 访问根路径
/
会自动跳转到/admin
- 前端路由和API路由将正常工作,不会有路径冲突
此方案通过调整路由结构和前端配置,解决了Gin框架中的路由冲突问题,同时保持了前端应用的正常功能。