Fiber项目常见问题源于初始化配置和中间件链错误:混用fiber.New()与fiber.Default()引发panic或I/O过载;StrictRouting关闭导致路由匹配失败;CORS配置冲突致预检失败;BasicAuth未显式返回401而失效。

Fiber 项目根本不是“安装失败”,而是初始化配置或中间件链没对上——启动 panic、静默退出、404 或 TTFB 异常高,90% 都出在这几个点。
fiber.New() 和 fiber.Default() 混用导致启动 panic 或日志压垮 I/O
fiber.Default() 是开发快捷键,但生产环境直接用它,等于主动埋雷。它默认挂载 Logger、Recover、RequestID 三个中间件,而 Logger 默认打印全部请求头(含 Authorization、Cookie),不仅泄露敏感信息,还会让 SD 卡 I/O 拉满;Recover 在 panic 后仍可能输出未清洗的堆栈,触发二次崩溃。
- 生产环境必须用
fiber.New()初始化,禁用所有默认中间件 - 如需日志,只记录异常:用
fiber.Logger(func(c *fiber.Ctx) bool { return c.Response().StatusCode() >= 400 }) - 关掉启动 banner:
fiber.New(fiber.Config{DisableStartupMessage: true}) - 别在
main()里写app := fiber.Default(); app.Use(fiber.Logger())—— 这是 Logger 被注册了两遍的典型写法
StrictRouting 关闭后路由全乱套,/user/123 和 /user/:id 都 404
Fiber 默认开启 StrictRouting: true,这是安全边界。一旦手动设成 false,路径归一化会把 /user/123/ 和 /user/123 当作同一路径处理,反而破坏参数提取逻辑,导致 c.Params("id") 始终为空,甚至让静态路由(如 /users/export)覆盖参数路由(如 /users/:id)。
- 别碰
StrictRouting配置项,保持默认值即可 - 注册顺序必须是:先带参数的路由(
/users/:id),再同前缀的静态路由(/users/export) - 检查访问路径是否和路由模板完全一致:注册
/api/v1/post/:id,就别访问/api/v1/post/7/(结尾斜杠) - 调试时加一行
fmt.Println("route:", c.Route().Path),确认当前请求真匹配到了你写的那条路由
CORS 中间件配错导致 OPTIONS 请求 404 或前端收不到响应头
加了 cors.New() 还报 CORS error?大概率是 AllowOrigins: "*" 和 AllowCredentials: true 同时启用。浏览器会直接丢弃响应,控制台只显示模糊错误,连状态码都不给你看。
- 只要开了
AllowCredentials: true,AllowOrigins就必须是具体域名列表,例如[]string{"http://localhost:5173", "https://myapp.com"} - 预检请求(OPTIONS)失败,常因漏配
AllowMethods或AllowHeaders:确保AllowMethods包含实际用到的动词(如"PUT"、"DELETE"),AllowHeaders包含"Authorization"、"Content-Type"等非简单头 - 别全局
app.Use(cors.New()),优先按路径分组:api := app.Group("/api", cors.New()) - 中间件顺序很重要:CORS 必须在鉴权、日志等中间件之前,否则预检请求可能被拦截
BasicAuth 中间件注册后无效果,或全站返回 401
fiber.BasicAuth() 不是“自动拦截器”,它只解析 Authorization 头并校验账号密码,不自动返回 401,也不阻止后续 handler 执行。常见错误是注册完就以为完事了,结果请求照常往下走;或者校验失败后没 return,又调了 c.Next(),导致响应已发、后续逻辑还在跑。
- 必须在中间件函数内显式处理失败分支:
c.Status(401).SendString("Unauthorized"); return - 放行路径才调
c.Next(),失败路径里绝不能调 - 别全局
app.Use(fiber.BasicAuth(...)),改用分组:auth := app.Group("/admin", fiber.BasicAuth(...)) - 密码比对务必用
subtle.ConstantTimeCompare,别用==或strings.EqualFold
真正卡住人的从来不是框架本身,而是初始化方式、中间件执行时机、路径匹配精度这些细节——它们不报错,但会让整个服务处于“假活”状态:进程在跑,日志有输出,请求有响应,就是逻辑不对。多打一行 c.Route().Path 和 c.Response().StatusCode(),比反复重装依赖管用得多。











