ctx.request().body不可重复读取,因go标准库中http.request.body是一次性流;iris默认缓冲原始体供readjson等使用,首次读取后即耗尽;应使用ctx.getbody()安全多次读取,或提前调用ctx.resetbodyreader()重置流。

不能直接用 ctx.Request().Body 二次读取,必须用 ctx.GetBody() 或提前调用 ctx.ResetBodyReader() —— 否则会返回空或 panic。
为什么 ctx.Request().Body 读不到原始数据?
Iris(v12)默认会对请求体做一次缓冲读取,用于内部的 ReadJSON、ReadForm 等方法。一旦 Body 被读过(哪怕只调用了一次 io.ReadAll(ctx.Request().Body)),底层的 http.Request.Body 就会被消耗掉,后续再读就是空的。
- 常见错误现象:
io.ReadAll(ctx.Request().Body)第二次调用返回[]或直接 panic - 根本原因:Go 标准库的
http.Request.Body是一次性流,不可重放 - Iris 的
ctx.GetBody()内部已缓存原始字节,是安全的多次读取入口
ctx.GetBody() 是最简单可靠的原始体读取方式
它返回 []byte,不校验 Content-Type,不解析结构,也不修改上下文状态,适合日志记录、签名验证、透传等场景。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- 直接调用:
raw, err := ctx.GetBody(),成功时raw是完整原始字节 - 如果请求体很大(比如上传文件),注意内存占用,
GetBody()会把整个 body 加载进内存 - 若需流式处理大 body,请改用
ctx.Request().Body+ctx.ResetBodyReader()配合io.Copy,但必须确保没被其他方法提前读过
需要流式读取时,必须手动重置 Body Reader
当你要用 io.Copy 或 json.NewDecoder 直接消费 ctx.Request().Body(例如转发到下游服务),得先告诉 Iris:“别再管这个 Body 了,我要自己来”。
- 调用
ctx.ResetBodyReader()后,ctx.Request().Body才恢复为原始未读状态 - 必须在任何
ReadJSON、ReadForm、GetBody()之前调用,否则无效 - 示例:
ctx.ResetBodyReader() decoder := json.NewDecoder(ctx.Request().Body) var v MyStruct err := decoder.Decode(&v)
容易被忽略的关键点
ctx.GetBody() 返回的是拷贝,修改它不影响后续解析;但如果你调用了 ctx.ReadJSON(&v),再调 GetBody() 依然能拿到原始数据 —— 因为 Iris 缓存发生在第一次读取前。真正危险的是绕过 Iris、直接碰 ctx.Request().Body 却忘了重置。










