
Go 的 http 包默认不自动提供静态文件,需显式配置 http.FileServer 并结合 http.StripPrefix 将特定 URL 路径映射到本地目录,才能让 HTML 中的 /assets/js/app.js 等引用正常加载。
go 的 `http` 包默认不自动提供静态文件,需显式配置 `http.fileserver` 并结合 `http.stripprefix` 将特定 url 路径映射到本地目录,才能让 html 中的 `/assets/js/app.js` 等引用正常加载。
在 Go 中构建 Web 服务时,仅通过 http.ServeFile 返回 HTML 页面(如 templates/index.html)是不够的——浏览器会单独发起对 <script></script>、<link> 等标签中路径的 HTTP 请求,而这些请求若未被服务器明确处理,将返回 404 错误。根本原因在于:Go 的 http 默认路由是空的,所有非显式注册的路径均无处理器(handler),静态资源不会被自动提供。
✅ 正确做法是:为静态资源目录(如 assets/)单独注册一个文件服务处理器,并通过 URL 前缀(如 /assets/)进行路由隔离。推荐结构如下:
├── assets/ │ ├── js/ │ │ └── app.js │ └── css/ │ └── style.css ├── templates/ │ └── index.html └── main.go
对应 main.go 的关键代码:
func main() {
http.HandleFunc("/", rootHandler)
// 将 /assets/ 开头的请求映射到 assets/ 目录,并剥离前缀以正确解析路径
http.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("assets"))))
log.Println("Server starting on :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
func rootHandler(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "templates/index.html")
}⚠️ 注意事项:
立即学习“前端免费学习笔记(深入)”;
-
http.StripPrefix("/assets/", ...)必须存在:它会从请求路径中移除/assets/前缀,使http.FileServer能基于相对路径(如js/app.js)在assets/目录下准确查找文件;若省略,请求/assets/js/app.js会被当作assets/assets/js/app.js查找,导致 404。 - HTML 中需使用绝对路径引用静态资源,例如
<script src="/assets/js/app.js"></script>;避免相对路径(如js/app.js),因其依赖当前 HTML 所在 URL 的路径层级,在 Go 的单点路由(/)下极易失效。 -
http.Dir("assets")中的路径是相对于运行main.go的工作目录(非源码目录),建议使用os.Executable()或embed(Go 1.16+)提升可移植性;生产环境更推荐http.FS(os.DirFS("assets"))(Go 1.16+)或第三方库(如statik,packr)嵌入资源。
? 扩展提示:若需支持 SPA 的 History API(如 React/Vue 路由),可自定义 handler 实现 fallback 到 index.html;若需缓存控制、Gzip 压缩或 HTTPS 支持,建议引入 net/http/pprof、golang.org/x/net/http2 或成熟框架(如 Gin、Echo)。但对基础静态服务而言,上述 http.FileServer + StripPrefix 组合已简洁、安全且符合 Go 的惯用风格。


















