当前位置: 首页 > article >正文

利用golang embed特性嵌入前端资源问题解决

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'

问题解决步骤:

  1. 分析错误原因
    在Gin框架中,路由注册顺序和路径模式会导致冲突。当前代码在注册/api/service路由时,与之前注册的通配符路由/*filepath发生冲突。Gin不允许在同一个路径前缀上注册多个处理函数。
  2. 确定解决方案
    为了解决路由冲突问题,需要调整前端路由的基路径:
  • 将根路径/重定向到/admin
  • 修改前端构建配置,将静态资源的基路径设为/admin
  1. 修改Golang代码
    StartHttpService函数中:
- 添加根路径重定向:
  ```go
  r.GET("/", func(c *gin.Context) {
      c.Redirect(http.StatusMovedPermanently, "admin/")
  })
  • 修改静态文件服务路径:
r.StaticFS("/admin", http.FS(dist))
  1. 修改前端配置
    vite.config.js中添加base配置:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
  plugins: [vue()],
  base: '/admin/',
})
  1. 重新构建前端资源
    执行npm run build生成新的静态资源,并确保生成的文件与/admin路径匹配。
  2. 验证生效
    重新启动服务后:
  • 访问根路径/会自动跳转到/admin
  • 前端路由和API路由将正常工作,不会有路径冲突
    此方案通过调整路由结构和前端配置,解决了Gin框架中的路由冲突问题,同时保持了前端应用的正常功能。

http://www.kler.cn/a/589529.html

相关文章:

  • 【经验分享】SpringBoot集成WebSocket开发-03 使用WebSocketSession为每个对话存储独立信息
  • Vue3中正确解析RefImpl对象
  • Hyperlane:轻量、高效、安全的 Rust Web 框架新选择
  • Java 大视界 -- Java 大数据机器学习模型的对抗攻击与防御技术研究(137)
  • 为什么手机上用 mA 和 mAh 来表示功耗和能耗?
  • java学习总结:JSP、Servlet
  • vue3项目如何使用keepAlive?如何实现回退到这个页面时不刷新,跳转至这个页面时会刷新?
  • Redis主从集群和哨兵集群
  • CML(Current Mode Logic)电平详解
  • MyBatis XMLMapperBuilder 是如何解析 SQL 映射文件的? 它读取了哪些信息?
  • docker安装rabbitmq
  • pyyaml_include 2.x 版本使用说明
  • Spring Cloud Gateway 生产级实践:高可用 API 网关架构与流量治理解析
  • Linux应用软件编程(多任务:进程间通信)
  • Excel VBA实现智能合并重复元器件数据(型号去重+数量累加)
  • VSCode C/C++ 环境搭建指南
  • 云原生服务网格:微服务通信的神经中枢革命
  • 【AI知识管理系统】(一)AI知识库工具测评
  • 美颜SDK x AIGC:如何用滤镜API结合AI生成技术打造创意视觉特效?
  • CI/CD构建与注意事项