Fiber处理请求严格按注册的HTTP方法和路径匹配,未注册即404或405;参数分三类隔离:c.Params()读显式声明的路径占位符,c.QueryParam()读URL查询串,c.FormValue()/c.BodyParser()读对应Content-Type的请求体,混用必为空。

method="put" 的 HTML 表单当真。你发什么方法,它就收什么方法;你写什么路由,它就匹配什么路径。没注册的路径 + 方法组合,就是 404 或 405。
怎么取路径参数、查询参数和请求体?三者完全隔离
Fiber 把请求参数分成三块,内存不共享、解析逻辑不交叉,混用必为空:
-
c.Params("id")只读app.Get("/user/:id", ...)这种显式声明的路径占位符;没在路由里写:id,c.Params("id")永远返回空字符串 -
c.QueryParam("page")只解析 URL 查询串,比如/list?page=2&sort=desc;它和路径参数名可以重名,但值互不影响 -
c.FormValue("name")读application/x-www-form-urlencoded表单,c.BodyParser(&v)解 JSON 请求体;别用c.FormValue()去读 JSON 字段,也别对表单调c.BodyParser(),会 panic 或静默失败
高频踩坑:在中间件里存 c.Params("id") 的返回值到 map 或 goroutine 里 —— 因为 c.Params() 返回的是内部字节切片引用,下个请求复用该 fiber.Ctx 对象时,值就变了。要存必须先转成 string。
PUT/DELETE 请求为什么 404 或 405?先看 Network 面板
浏览器原生 <form method="put"> 是无效的,HTML 规范只认 get 和 post,写上去会被忽略,退化成 GET。这不是 Fiber 的问题,是浏览器行为。
- 真 PUT/DELETE 必须用 JS 发:fetch、axios、XMLHttpRequest
- Fiber 不做方法重写,所以不用配
_method隐藏字段,也不需要类似 Spring 的HiddenHttpMethodFilter - 404:路由没注册,比如写了
app.Put("/user", ...),但请求是PUT /users - 405:路径存在,但方法不匹配,比如只注册了
app.Post("/user", ...),却用 PUT 访问 - 跨域带
Authorization等自定义 Header 时,浏览器会先发 OPTIONS 预检 —— 若没配cors.New(),预检就卡住,Network 面板只看到一个失败的 OPTIONS 请求
中间件里想打印请求体?不能直接调 c.Body()
c.Body() 是一次性消费流,中间件里调一次,后续 handler 再调就空了;更糟的是,如果 body 含 BOM 或非 UTF-8 字节(比如微信 XML 回调),c.Body() 会直接 panic。
- 正确做法:用
c.Request().Body()拿原始io.ReadCloser,io.ReadAll()读成字节切片,再用bytes.NewReader(bodyBytes)封装回去,最后调c.Request().SetBodyStream()恢复可读状态 - 生产环境注意长度限制:大文件全读会吃光内存,日志建议只截前 512 字节
- 别在中间件里用
c.FormValue()或c.Struct()做校验 —— 它们内部会触发 body 解析,且只对特定 Content-Type 生效,对 raw XML 或二进制无效
favicon.ico 怎么配才不 404?static 中间件默认不处理它
app.Use(static.New("./public")) 只响应带前缀的路径(如 /assets/xxx),而浏览器发的 GET /favicon.ico 是根路径请求,中间件根本不会命中。
- 最简方案:
app.Static("/favicon.ico", "./public/favicon.ico")—— Fiber 提供的快捷方法,专为单文件挂载设计 - 若需加缓存头或 fallback 逻辑,改用
app.Get("/favicon.ico", func(c *fiber.Ctx) error { ... })自定义 handler,手动读文件并设c.Type("image/x-icon").Send(data) - 别忽略 iOS:Chrome/Firefox 发一次
/favicon.ico,Safari 还会额外发/apple-touch-icon.png,甚至/apple-touch-icon-precomposed.png,这些都得单独配 - 如果用了 Nginx 或 CDN,确认它们没把
/favicon.ico请求提前截断或返回默认图标
真正麻烦的从来不是“怎么配”,而是“配完之后浏览器还在发两次请求,而你只拦住了一次”。


















