请求进入 Fiber 的第一个钩子是 app.Use()。它注册中间件,对所有匹配路径的请求(无论 HTTP 方法)都会触发;而 app.Get() 等只在方法和路径都匹配时执行。

请求进入 Fiber 的第一个钩子是 app.Use() 还是 app.Get()?
是 app.Use()。它注册的是中间件,对所有匹配路径的请求(无论 HTTP 方法)都会触发;而 app.Get() 等路由处理器只在方法和路径都匹配时才执行。
常见错误是把鉴权、日志、CORS 等通用逻辑写在 app.Get() 里,导致 POST/PUT 请求绕过校验。正确做法是:
-
app.Use()放全局中间件(如logger.New()、cors.New()) -
app.Get()/app.Post()放业务逻辑,且只处理对应方法 - 路径匹配顺序重要:Fiber 按注册顺序遍历中间件和路由,
app.Use("/api", ...)会拦截所有以/api开头的请求,包括/api/users/123
为什么 c.Next() 必须显式调用才能进入下一个处理器?
Fiber 不自动链式调用,c.Next() 是手动控制流程的关键。漏掉它,后续中间件和路由处理器就完全不会执行——这是最常被忽略的“静默失败”点。
典型场景:
- 鉴权中间件验证失败后直接
c.Status(401).SendString("unauthorized"),但忘了return,结果继续执行c.Next(),业务逻辑仍被调用 - 日志中间件在
c.Next()前记录开始时间,之后记录耗时,若没调用c.Next(),耗时永远为 0 -
c.Next()不会自动捕获 panic,需配合recovery.New()中间件
c.Context 的生命周期何时结束?能复用吗?
c.Context 实例由 Fiber 在每次请求到来时从内存池中复用并重置,响应写出(c.Send()、c.JSON() 等)或连接关闭后即被归还到池中。不能跨请求保存或并发读写。
容易踩的坑:
- 在 goroutine 中直接使用
c(比如异步发消息),可能访问到已被重置的上下文 → 应复制需要的数据,如path := c.Path() - 给
c.Locals存对象后,在中间件里修改该对象,下游处理器看到的是同一份引用 → 若需隔离,应深拷贝或改用c.Context.Value()+ 自定义 key -
c.IP()、c.UserAgent()等方法内部做了缓存,多次调用无性能问题,但不要依赖c.Context().Value()存原始context.Context,Fiber 已封装好
Response 写出后还能修改状态码或 Header 吗?
不能。一旦调用 c.Send()、c.JSON()、c.Status(200).Send() 等写出响应体,底层 HTTP writer 就已 flush header 和部分 body,再调用 c.Status(500) 或 c.Set("X-Trace", "...") 会静默失败(开发模式下 Fiber 可能报 http: superfluous response.WriteHeader 错误)。
实际建议:
- 所有 Header 设置、状态码设定必须在任何
Send*调用之前完成 - 用
c.Response().Header.Add()替代c.Set()如果需要追加而非覆盖(如多个Set-Cookie) - 调试时开启
fiber.Config{DisableStartupMessage: false},启动日志会提示是否启用了server header等隐式行为
真正复杂的生命周期控制往往不在框架文档里,而在你忘记 return 和误判 c.Next() 执行时机的那几行代码里。


















