根本原因是请求路径与本地文件路径未对齐:app.Static("/static", "./public")要求浏览器访问 /static/logo.png 时,Fiber 去当前工作目录下的 ./public/logo.png 查找,而工作目录不等于 main.go 所在目录,且 ./public 末尾不能带斜杠。

app.Static() 是最直接的配置方式,但多数 404 不是函数没调用,而是路径映射错、工作目录不对或前缀不匹配。
为什么 app.Static() 挂载后仍 404
根本原因不是代码写错,而是请求路径与本地文件路径没对齐:
-
app.Static("/static", "./public")表示:浏览器访问/static/logo.png→ Fiber 去找当前工作目录下的./public/logo.png - 工作目录 ≠
main.go所在目录:用go run main.go启动时,工作目录是终端当前路径;IDE 运行需手动检查其“Working Directory”设置 -
./public末尾不能带斜杠(./public/在某些 Go 版本下会 panic) - 如果文件实际在
assets/css/main.css,那必须写成app.Static("/static", "./assets"),然后访问/static/css/main.css—— 写成/static/main.css就必然 404
app.Static() 和 app.Use(static.New()) 到底用哪个
二者底层不同,适用场景明确:
-
app.Static("/static", "./public"):快捷封装,自带缓存头(Cache-Control)、索引页(Index: "index.html")、目录浏览开关(Browse: false默认),适合常规静态资源服务 -
app.Use("/static", static.New("./public")):中间件模式,只做路径前缀映射,不加缓存头、不处理index.html、不支持Browse,且无法响应/static(无尾部斜杠)这种请求 - 想控制
MaxAge、启用压缩或自定义 MIME 类型?必须用app.Static()并传入fiber.StaticConfig{}
favicon.ico 怎么配才不丢
浏览器发的是根路径请求 /favicon.ico,static.New() 默认不处理它,因为没挂载对应前缀:
- 最简方案:
app.Static("/favicon.ico", "./public/favicon.ico")—— 单独挂一个文件,Fiber 自动加Cache-Control头 - 别写
app.Use(static.New("./public"))然后指望它命中/favicon.ico:它只响应带前缀的路径,而该请求无前缀 - 需要日志或 fallback 逻辑?用显式路由:
app.Get("/favicon.ico", func(c *fiber.Ctx) error { ... }),手动读取并设c.Type("image/x-icon") - 注意 iOS 设备还会请求
/apple-touch-icon.png,也得单独配,否则控制台报 404
生产环境必须加固的三件事
static.New() 或 app.Static() 默认都不防攻击,上线前这几项漏一不可:
- 路径遍历:默认
SafeNavigation: false,../../../etc/passwd可能被解析。要么用static.New("./public").EnableDirListing(false),要么前置中间件拦截含".."的c.Path() - 防盗链:必须把 referer 中间件放在
static.New()之前,顺序反了就失效;用url.Parse(c.Get("Referer")).Hostname()提取 host,别字符串匹配 - 缓存与 MIME:
static.New()不设Cache-Control,也不校验文件是否存在——目录不存在时静默返回 404,建议启动时用os.Stat()主动检查路径
./public 这个点到底是相对谁。


















