应统一处理尾斜杠重定向:启用StrictRouting时,通过中间件对非根路径的尾斜杠请求301跳转至无斜杠路径,或显式注册双路由并复用handler;注意c.Redirect()调用时机、状态码、URL格式及响应头设置。

重定向带尾斜杠的请求到无尾斜杠路径
Fiber 默认开启 StrictRouting: true,所以 /users/ 和 /users 是两个独立路由。前端发来带尾斜杠的请求(比如 GET /users/),而你只注册了 app.Get("/users", handler),就会直接 404——这不是漏写路由,是匹配没对齐。
别全局关掉 StrictRouting,否则像 /users/:id 这种带参数的路由可能被 /users 意外捕获,c.Params("id") 拿不到值。
- 加一个统一中间件,在
app.Use()里处理:检查c.Path()是否以"/"结尾且不是根路径,是则 301 跳转到去尾版本 - 示例代码中必须用
strings.TrimSuffix(c.Path(), "/"),不能用strings.TrimRight(c.Path(), "/"),否则//users//会被错误截成//users - 上线前同步确认所有前端、SDK、OpenAPI 文档都用无尾斜杠路径,否则重定向会变成“隐性兼容补丁”,越积越多
显式注册两条路由并做内部重定向
有些场景不适合 301(比如 API 客户端不自动跟随重定向,或你不想暴露路径变更),那就显式注册 /users 和 /users/ 两条路由,后者内部跳转。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
注意:用 c.Redirect() 是客户端重定向(发 301/302 响应),而 c.Next() 或 c.Rewrite() 是服务端内部转发(URL 不变)。Fiber 没有内置 Rewrite,但你可以手动复用逻辑:
-
app.Get("/users/", func(c fiber.Ctx) error { return usersHandler(c) })—— 直接复用 handler 函数 - 避免复制粘贴逻辑,把业务逻辑抽成普通函数,两个路由都调它
- 不要在
/users/的 handler 里写c.Status(301).Redirect(...),Fiber 的c.Redirect()已含状态码,重复设会 panic
ctx.Redirect() 的常见陷阱
c.Redirect() 看似简单,但几个细节不注意就会返回空响应、状态码错乱或头丢失。
- 第二个参数是 HTTP 状态码,必须是 3xx,常用
301(永久)或302(临时);传300或200会导致浏览器不跳转 - 重定向目标 URL 必须是完整路径(如
"/users")或绝对地址(如"https://api.example.com/users");相对路径如"users"会被拼到当前 host 后,容易出错 -
c.Redirect()不会自动设置Location以外的响应头,如果需要带X-RateLimit-Reset或自定义头,得手动c.Set(),且必须在c.Redirect()之前调用 - 如果 handler 已经写了响应体(比如先调了
c.JSON()),再调c.Redirect()会 panic:Fiber 不允许二次写响应
重定向与中间件执行链的关系
重定向本身是个响应动作,一旦执行,后续中间件和 handler 就不会再走。这点和 c.Next() 完全相反。
- 在权限中间件里,判断失败后调
c.Redirect("/login"),就该直接return,后面绝不能跟c.Next()—— 否则 Fiber 会报 “response already committed” - 想在重定向前记录日志?必须放在
c.Redirect()之前,因为之后c的生命周期已进入提交阶段 - 注意
c.Redirect()返回的是error,推荐写法是return c.Redirect(...),而不是c.Redirect(...); return nil,避免误触发后续逻辑


















