Fiber 的 app.Use() 无法跳过路由,因其是前缀挂载器而非过滤器;正确做法是:单个路由不传中间件、用空中间件路由组、或将需跳过的路由注册在 app.Use() 之前。

为什么 app.Use() 无法跳过某条路由
Fiber 的 app.Use() 注册的是全局中间件,它对所有匹配路径(包括 /api/*、/admin/*)都生效,**没有内置“排除路径”机制**。你写 app.Use("/api", middleware) 并不是“只作用于 /api”,而是“把中间件挂载到以 /api 开头的路径前缀下”——这和“跳过”完全相反。
正确做法:用路由级注册替代全局 Use
真正跳过中间件,本质是让那条路由**不进入中间件链**。Fiber 提供两种干净方案:
- 单个路由直接不传中间件:
app.Get("/health", func(c *fiber.Ctx) error { return c.SendString("ok") })—— 它绕过了所有app.Use()链 - 对已有全局中间件(如日志、鉴权),想放行特定路径,就**改用路由组 + 空中间件**:
public := app.Group("", func(c *fiber.Ctx) error { return c.Next() }),再注册public.Get("/status", handler) - 若必须保留
app.Use(logger),又想让/metrics不被日志刷屏,就把它挪到app.Use()**之前**注册:app.Get("/metrics", handler)→app.Use(logger)→ 其他路由
常见翻车点:StrictRouting 和路径尾部斜杠
你以为跳过了 /health,但前端实际请求的是 /health/,而你没注册这个带斜杠的版本 —— Fiber 默认开启 StrictRouting: true,它会把两者视为不同路由,导致请求掉进全局中间件里被拦住。
- 检查真实请求路径是否带尾部斜杠(用
c.OriginalURL()或抓包确认) - 要么显式注册两个:
app.Get("/health", h)和app.Get("/health/", h) - 要么加一层重定向中间件,统一收口(但注意:重定向本身也是中间件,要放在最外层)
回调类接口(如微信支付)必须彻底隔离中间件
微信/支付宝回调 POST 请求常无 Content-Length、含原始 XML、且要求响应体严格为 success 或特定 XML。任何 BodyLimit、JSON 解析、表单自动解析中间件都会提前读取或篡改 body,导致验签失败。
- 绝对不要用
app.Use("/pay/callback", ...)或任何全局中间件覆盖该路径 - 必须用
app.Post("/pay/callback", func(c *fiber.Ctx) error { ... })单独注册 - 在 handler 内手动调
c.Request().Body()读原始字节,别碰c.Body()或c.FormValue() - 响应时用
c.Status(200).SendString("success"),禁止 JSON、HTML、重定向等额外逻辑
真正“跳过”的关键不在配置开关,而在注册位置和路径精确性。很多人卡在调试时发现中间件还是执行了,其实只是请求路径和路由注册没对齐,或者误以为 app.Use("/xxx", m) 是条件启用——它从来不是过滤器,而是前缀挂载器。


















