Beego 的 ParseForm 无法解析 JSON 请求体,仅支持 application/x-www-form-urlencoded 和 multipart/form-data;正确做法是通过 this.Ctx.Input.RequestBody 读取并手动 json.Unmarshal 解码,需确保结构体字段导出且含 json tag。

Beego 中 ParseForm 不能解析 JSON 请求体
直接调用 ParseForm 无法获取 POST/PUT 请求中以 application/json 发送的字段——它只处理 application/x-www-form-urlencoded 和 multipart/form-data。如果你发现 this.Input().Get("xxx") 或 this.GetString("xxx") 返回空,大概率是客户端发了 JSON 但服务端没走对解析路径。
正确做法是:先判断 Content-Type,再选择解析方式。Beego 默认不自动解析 JSON,必须手动读取并解码。
用 this.Ctx.Input.RequestBody 读取原始 JSON 并解码
这是最常用、最可控的方式。适用于结构明确的 JSON 请求体(如 {"name":"alice","age":25})。
-
this.Ctx.Input.RequestBody是[]byte,已由 Beego 自动读取并缓存,可多次调用,无需重复io.ReadAll - 必须显式指定结构体或
map[string]interface{}接收,且字段需导出(首字母大写)并加jsontag - 注意编码问题:Beego 默认按 UTF-8 处理,若请求含 BOM 或非 UTF-8 编码,
json.Unmarshal会报invalid character
示例:
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
func (this *MainController) Post() {
var u User
if err := json.Unmarshal(this.Ctx.Input.RequestBody, &u); err != nil {
this.Data["json"] = map[string]string{"error": "invalid json"}
this.ServeJSON()
return
}
// u.Name, u.Age 现在可用
}
使用 this.ParseForm 前必须确保请求是表单格式
如果你确实收到的是 application/x-www-form-urlencoded(比如前端用 FormData 或 axios.post(url, {a:1}) 未设 header),那 ParseForm 才有效。
- Beego 要求在
Prepare()或 handler 开头调用this.ParseForm(),否则GetString等方法返回空 - 如果误对 JSON 请求调用
ParseForm,不会报错,但所有字段都为空——这是最常见的静默失败 - 可通过
this.Ctx.Input.Header("Content-Type")日志确认实际类型,避免凭经验猜测
全局启用 JSON 自动绑定需重写 Prepare 方法
Beego 不提供开箱即用的 JSON 自动绑定(类似 Gin 的 BindJSON),但可在基类 Controller 中统一处理:
- 检查
Content-Type是否包含json,若是则尝试解码到预定义结构体字段(如this.JsonData) - 不要覆盖
ParseForm行为,而是补充逻辑:表单走原有流程,JSON 走新分支 - 注意性能:每次请求都做字符串匹配和
json.Unmarshal有开销,简单接口够用;高频接口建议按需解析,而非全局强制
容易被忽略的一点:RequestBody 在首次读取后不会清空,但如果你在中间件或 Prepare 中提前调用了 json.Unmarshal,后续 handler 再用同样字节解码没问题;但如果中间件里做了 io.ReadAll(this.Ctx.Request.Body),会导致 RequestBody 为空——Beego 的 RequestBody 是惰性读取,依赖原始 Body 可读性。

















