全局中间件必须用app.use()注册,它不区分http方法且按路径前缀严格匹配,执行顺序严格遵循代码书写顺序,错误使用会导致请求短路或功能失效。

全局中间件必须用 app.Use() 注册,不能用 app.Get() 或 app.Group()
想让中间件对所有路由生效,唯一正确入口是 app.Use()。它不区分 HTTP 方法,也不依赖路径是否匹配路由定义——只要请求路径以指定前缀开头(或无前缀时匹配全部),就会执行。比如 app.Use(logger.New()) 会拦截所有请求;而 app.Use("/api", cors.New()) 只作用于 /api 及其子路径(如 /api/users),但不会影响 /health。
常见错误是误把 app.Use() 当成只处理中间件的“专用函数”,然后在它里面手动调用 c.Next() 却忘了返回 error ——这会导致 handler 永远不执行。正确写法必须显式返回 c.Next() 的结果:
app.Use(func(c *fiber.Ctx) error {
log.Println("before handler")
err := c.Next() // 必须调用并传递 error
log.Println("after handler")
return err // 必须返回,否则 handler 被跳过
})
app.Use() 的前缀匹配规则容易被误解
前缀不是模糊搜索,而是严格按路径边界匹配。例如:
-
app.Use("/user")→ 匹配/user、/user/profile、/user/123/edit -
app.Use("/user")→ 不匹配/users、/username(因为后面不是/或路径结束) -
app.Use("/")→ 等价于无前缀,匹配所有请求
如果你希望中间件只在根路径生效,别写 app.Use("/"),而应改用 app.Get("/", middleware, handler) 这种路由级方式,否则它会意外覆盖所有子路径。
多个 app.Use() 的执行顺序严格按代码顺序
Fiber 不会重排中间件,谁先注册谁先执行。这意味着:
- 日志中间件应放在最前面,才能记录完整生命周期
- 恢复 panic 的
recover()中间件必须放在靠前位置,否则后续中间件 panic 后无法捕获 - 如果用了
app.Use("/api", auth)和app.Use(rateLimit),后者会作用于全部路径,包括/health—— 若只想限流 API,得改成app.Use("/api", rateLimit, auth)
特别注意:全局 app.Use() 和路由组 app.Group("/admin", m1) 是正交的,但执行时仍按书写顺序叠加。比如先写 app.Use(m0),再写 api := app.Group("/api", m1),那么访问 /api/users 的执行链是 m0 → m1 → handler。
自定义中间件函数签名和返回值不能错
所有中间件必须满足 func(*fiber.Ctx) error 类型。任何偏差都会导致编译失败或运行时 panic:
- 返回值类型写成
void、nil或不写,Go 编译器直接报错 - 参数类型写成
*http.Request或context.Context,Fiber 无法识别,启动时报cannot use ... as fiber.Handler - 中间件里启动 goroutine 并传入
c是危险操作 ——c是从 sync.Pool 复用的,可能在 handler 返回后已被回收
真正安全的做法是:只在当前 goroutine 内使用 c,若需异步处理,应提前提取必要字段(如 c.IP()、c.Path())再传入新 goroutine。











