使用go:embed在Gin中服务React静态文件,前端路由刷新报404错误
问题根因
React SPA 采用客户端路由实现页面切换,通过react-router-dom跳转时仅在浏览器端修改路由地址,不会向后端发起请求,因此访问正常。但直接刷新/calendar这类路径时,浏览器会主动向后端发起对应路径的GET请求,你的后端没有配置对应路径的处理逻辑,就会命中默认的NoRoute规则返回404。
修复方案
你不需要为每个前端路由单独配置static.Serve中间件,只要修改NoRoute的处理逻辑,将所有未匹配到后端接口的非静态资源请求,都返回SPA的入口文件index.html,让前端接管路由判断即可,修改步骤如下:
- 删除冗余的单路由静态服务配置,这两行完全不需要,后续新增前端路由也不需要修改后端代码:
// 以下两行代码删除 // router.Use(static.Serve("/login", fs)) // router.Use(static.Serve("/calendar", fs))
- 修改NoRoute处理逻辑,记得提前引入
strings包:
import "strings" // 没有导入的话先加上 router.NoRoute(func(c *gin.Context) { path := c.Request.URL.Path // 静态资源请求不存在的话走正常404逻辑 staticSuffixes := []string{".css", ".js", ".json", ".png", ".jpg", ".svg", ".ico"} for _, suffix := range staticSuffixes { if strings.HasSuffix(path, suffix) || strings.HasPrefix(path, "/static/") { c.JSON(404, gin.H{ "code": "PAGE_NOT_FOUND", "message": "Page not found", }) return } } // 其他请求统一返回前端入口index.html content, err := reactStatic.ReadFile("build/index.html") if err != nil { c.JSON(500, gin.H{"code": "SERVER_ERROR", "message": "加载前端资源失败"}) return } c.Data(200, "text/html; charset=utf-8", content) })
修改完成后重新编译运行项目即可,所有前端路由刷新都会正常加载。
内容的提问来源于stack exchange,提问作者Harsh Agarwal
相关产品推荐
相关产品推荐

