go 的 fiber 框架不提供全局 mime 配置,需在 fiber.new() 前调用 mime.addextensiontype 手动注册 .webp、.woff2 等扩展名及其标准 mime 类型,否则静态文件响应会因 mime.typebyextension 查不到而降级为 text/plain 或错误类型。

Go 的 fiber 框架本身不提供全局 MIME 类型配置入口,它默认依赖 Go 标准库的 mime.TypeByExtension 查表机制;你要加 .webp、.woff2、.mjs 等类型,得手动注册到 Go 的 mime 包里,且必须在 fiber 启动前完成。
Go 的 mime 包才是实际生效层
fiber 所有静态文件响应(比如 c.SendFile、app.Static)最终都调用 http.ServeContent 或 http.ServeFile,而这些函数内部靠 mime.TypeByExtension(".webp") 获取类型——它查的是 Go 运行时内置的 mime.types 表,不是 Apache/Nginx 那套。
这个表默认只含常见后缀(.png、.js、.css 等),.webp、.woff2、.avif、.mjs 等都不在其中,所以直接返回会是 text/plain 或空值,浏览器拒绝执行或解析失败。
- 必须在
main()开头、fiber.New()之前调用mime.AddExtensionType - 扩展名必须带点:
".webp"✅,"webp"❌ - MIME 类型要写标准值:优先用
image/webp而非application/webp,用font/woff2而非application/font-woff2 - 重复注册无害,但没必要;同一扩展名多次调用,以最后一次为准
fiber.Static 和 c.SendFile 都受此影响
你用 app.Static("/static", "./public") 提供 /static/logo.webp,或者用 c.SendFile("./data/config.json") 返回 JSON 配置,只要扩展名不在 Go 默认表里,就会触发 fallback 行为——http.DetectContentType 读前 512 字节猜类型,结果不稳定(比如空 JSON 文件可能被当成 text/plain)。
这不是 fiber 的 bug,是 Go HTTP 库的设计逻辑。你不注册,它就真不知道 .json 应该是 application/json。
-
app.Static不支持传入自定义 MIME 映射函数,无法绕过mime.TypeByExtension -
c.SendFile同理,也不能指定Content-Type参数,它自动推导 - 若需完全控制响应头,只能改用
c.Status(200).SendBytes+ 手动c.Set("Content-Type", "..."),但失去断点续传、ETag、Last-Modified 等内置能力
正确注册示例(含常见现代格式)
把这段代码放在 main() 函数最开头:
func main() {
// 注册额外 MIME 类型(必须在 fiber.New 前)
mime.AddExtensionType(".webp", "image/webp")
mime.AddExtensionType(".avif", "image/avif")
mime.AddExtensionType(".woff2", "font/woff2")
mime.AddExtensionType(".mjs", "application/javascript")
mime.AddExtensionType(".wasm", "application/wasm")
mime.AddExtensionType(".json", "application/json")
mime.AddExtensionType(".yaml", "application/yaml")
mime.AddExtensionType(".toml", "application/toml")
app := fiber.New()
app.Static("/static", "./public")
app.Get("/config", func(c *fiber.Ctx) error {
return c.SendFile("./config.json") // 现在能正确返回 application/json
})
log.Fatal(app.Listen(":3000"))
}
注意:mime.AddExtensionType 是并发安全的,可多处调用;但别在 handler 里动态注册——它只影响后续请求,当前请求已进入 HTTP 处理链路,改了也白改。
最容易被忽略的一点:Go 的 mime 包注册是进程级的,一旦注册,所有依赖它的 HTTP 服务(包括 net/http 原生服务)都会共享这张表。如果你项目里混用了 fiber 和原生 http.ServeMux,它们会共用同一套映射规则——这既是便利,也是潜在冲突点。











