必须显式调用app.static()挂载静态资源,否则css/js等一律404;fiber模板引擎仅处理c.render(),不接管/static/*请求,静态服务需独立配置且路径必须严格匹配目录结构。

必须显式调用 app.Static(),否则所有 CSS/JS 图片等静态资源一律 404。Fiber 的模板引擎(如 html.New())和路由系统完全不处理 /static/style.css 这类请求,它只负责 c.Render();静态文件服务是独立功能,不开启就等于没挂载。
为什么 app.Static() 不生效?常见配置错误
多数 404 都不是代码写错,而是路径或目录结构不匹配:
-
app.Static("/static", "./public")表示:浏览器访问/static/logo.png时,Fiber 去找本地./public/logo.png—— 注意是相对当前工作目录,不是相对于main.go所在路径 - 如果实际文件放在
assets/css/main.css,但你写成app.Static("/static", "./assets"),那访问/static/css/main.css才对;写成/static/main.css就会 404 - Windows 下路径分隔符不影响,但
./public末尾不能带斜杠(./public/在某些 Go 版本下可能触发空目录 panic) - 如果你用
go run main.go启动,工作目录就是终端当前路径;用 IDE 运行时需检查其默认工作目录设置
app.Static() 和 app.Use(fiber.Static()) 的区别
二者都能提供静态服务,但行为不同:
-
app.Static("/static", "./public")是快捷封装,自动启用缓存头、目录浏览(Browse: false默认)、索引页(Index: "index.html")等,适合常规场景 -
app.Use(fiber.Static("./public"))是中间件模式,只映射根路径(即GET /xxx直接查./public/xxx),不支持前缀路径(比如无法实现/static/*→./public),也不带内置缓存或索引逻辑 - 想控制
MaxAge、Browse或Compress,必须用app.Static()并传入fiber.StaticConfig{}
需要目录浏览(Browse: true)?别依赖 app.Static() 自动返回 HTML
app.Static("/assets", "./assets", fiber.StaticConfig{Browse: true}) 确实能在访问 /assets/(末尾带斜杠)且该路径下没有 index.html 时返回 HTML 列表页,但它:
- 只对
GET /assets/生效,GET /assets(无斜杠)直接 404 - 不返回 JSON,不能当 API 用;想做
GET /api/files返回文件名数组?得自己写 handler +os.ReadDir() - 不支持过滤、排序、权限校验;HTML 页面样式不可定制,也没法加认证
- 一旦
./assets/index.html存在,/assets/就返回那个文件,不会触发目录列表
真正要暴露文件列表,注册一个显式路由更可控:app.Get("/api/files", listFilesHandler),里面用 os.ReadDir("./assets") 手动读取并 c.JSON() 返回。静态服务和 API 必须分开设计,混用只会让逻辑变脆。











