Fiber默认不自动解析JSON,ctx.Body()仅返回原始字节流,需显式调用ctx.BodyParser(&req)或配置JSONDecoder中间件;失败主因是字段未导出、json tag缺失/错误、类型不匹配或Content-Type不符。

接收 JSON 时 Body 解析失败,ctx.Body() 返回空字符串
这是最常见问题:Fiber 默认不自动解析 JSON,ctx.Body() 只是原始字节流,如果没手动解析或启用中间件,直接转结构体必然失败。
必须显式调用 ctx.BodyParser() 或提前注册 fiber.JSONDecoder 中间件。推荐后者,一劳永逸:
app := fiber.New(fiber.Config{
JSONEncoder: json.Marshal,
JSONDecoder: json.Unmarshal,
})
// 不需要额外中间件,Fiber v2.40+ 已内置 JSON 解析支持
但注意:ctx.BodyParser() 仍需手动调用,它会根据 Content-Type: application/json 自动选择解码器。
ctx.BodyParser() 解析结构体失败的典型原因
常见错误不是语法问题,而是字段标签或类型不匹配:
- 结构体字段未导出(首字母小写),
json.Unmarshal无法赋值 - 缺少
json:标签,或拼写错误(如写成josn:) - 传入了
null但字段是非指针基础类型(如int),会 panic - JSON 字段名含下划线,但结构体标签没映射(如
"user_id"→UserID int `json:"user_id"`)
示例正确用法:
type LoginReq struct {
Username string `json:"username"`
Password string `json:"password"`
}
func handler(c *fiber.Ctx) error {
var req LoginReq
if err := c.BodyParser(&req); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": err.Error()})
}
// req.Username 已填充
return c.SendStatus(fiber.StatusOK)
}
处理嵌套对象或数组时的注意事项
Fiber 对嵌套 JSON 没特殊限制,但容易忽略两点:
- 深层嵌套结构体字段也必须全部导出 + 正确
json:标签 - 接收数组需定义切片类型,不能用
[]map[string]interface{}除非你真要泛型解析 - 如果前端发的是
application/json但内容其实是[{...}, {...}],结构体应定义为[]Item,再传地址给BodyParser
例如接收用户列表:
type User struct {
ID uint `json:"id"`
Name string `json:"name"`
}
func handler(c *fiber.Ctx) error {
var users []User
if err := c.BodyParser(&users); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "invalid JSON array"})
}
return c.JSON(users)
}
调试 JSON 接收问题的最快方式
别猜,直接看原始数据和错误细节:
- 用
string(c.Body())打印原始请求体,确认是否真为合法 JSON(有无 BOM、多余逗号、单引号) - 检查
c.Get("Content-Type")是否为application/json,否则BodyParser可能跳过解析 - 错误信息里出现
invalid character ...说明 JSON 格式错;cannot unmarshal ... into Go struct说明结构体不匹配 - 开发期可临时加
fmt.Printf("raw: %s\n", string(c.Body())),上线前删掉
真正棘手的是前端发了 text/plain 却声称是 JSON,或者用了 JSON.stringify() 但后端没设对 header —— 这类问题不会报错,只是字段为空。











