使用Golang EmbedFS部署Angular编译应用遇阻求助
问题:Golang EmbedFS 部署 Angular 编译应用出现静态资源404
项目结构
-- project | - cmd | - web | - main.go - routes.go - handlers.go - other go files ... - ui | - efs.go - angular // Angular编译应用存放目录
相关代码
efs.go
package ui // 使用EmbedFS托管Angular编译产物 import ( "embed" ) //go:embed "angular" var AngularFiles embed.FS
routes.go
package main import ( "io/fs" "net/http" "project/ui" "github.com/julienschmidt/httprouter" // 第三方路由库 ) func (app *application) routes() http.Handler { router := httprouter.New() /* 尝试在根路径"/"挂载EmbedFS(Angular编译产物) */ fsys, err := fs.Sub(ui.AngularFiles, "angular") if err != nil { panic(err) } fileServer := http.FileServer(http.FS(fsys)) router.Handler(http.MethodGet, "/", fileServer) /* 其他业务路由 */ // 此处省略其他路由代码 return router }
问题现象
访问根URL(如http://localhost:9090)时浏览器显示空白页,控制台显示index.html已成功加载,但所有JS、CSS等静态资源请求返回404错误。所有静态文件与index.html均位于angular目录下。
错误原因与解决方法
错误原因
当前路由仅将**根路径"/"**映射到文件服务器,而Angular的静态资源请求路径为/main.js、/styles.css这类子路径。httprouter不会自动将这些子路径请求转发到文件服务器,导致资源无法找到。
解决方法
修改路由配置,使用通配符路由匹配所有GET请求的静态资源路径,同时确保业务API路由优先匹配:
package main import ( "io/fs" "net/http" "project/ui" "github.com/julienschmidt/httprouter" ) func (app *application) routes() http.Handler { router := httprouter.New() // 1. 先定义业务API路由(优先匹配) // router.Handler(http.MethodGet, "/api/user", app.userHandler) // router.Handler(http.MethodPost, "/api/login", app.loginHandler) // ... 其他业务路由 // 2. 处理Angular静态资源:使用通配符匹配所有剩余GET请求 fsys, err := fs.Sub(ui.AngularFiles, "angular") if err != nil { panic(err) } // 创建文件服务器,并去除请求路径前缀,确保正确映射到EmbedFS中的文件 fileServer := http.StripPrefix("/", http.FileServer(http.FS(fsys))) router.Handler(http.MethodGet, "/*filepath", fileServer) return router }
关键说明
- 将业务API路由放在静态资源路由之前,保证API请求不会被静态资源路由拦截。
- 使用
"/*filepath"通配符匹配所有以"/"开头的GET请求,覆盖Angular所有静态资源路径。 http.StripPrefix("/", ...)用于确保请求路径直接对应EmbedFS中的文件路径(比如/main.js会直接查找fsys中的main.js)。
内容的提问来源于stack exchange,提问作者Vic VKh
相关产品推荐
相关产品推荐

