ctx.JSON() 是最直接的 JSON 响应方式,自动设置 Content-Type 并安全序列化 Go 值;慎用 ctx.StatusCode()+ctx.Write() 组合,易遗漏 header 或引发 panic;推荐中间件统一错误处理+自定义 Success 方法封装标准响应结构,并在鉴权等中间件中调用 ctx.JSON() 后立即执行 ctx.StopExecution() 防止重复响应。

ctx.JSON() 是最直接的 JSON 响应方式
调用 ctx.JSON() 会自动设置 Content-Type: application/json,序列化传入的 Go 值(map、struct、slice 等)并写入响应体。它底层用的是 Go 标准库 json.Marshal,不依赖额外配置。
常见错误现象:手动 ctx.ResponseWriter().Write([]byte(...)) 拼 JSON 字符串,结果中文乱码、字段丢失、空值没处理、缺少 Content-Type 头 —— 浏览器或 curl 可能解析失败,Postman 显示 raw text。
使用场景:RESTful API 的成功响应,比如用户登录后返回 {"token": "xxx", "user_id": 123}。
ctx.JSON(200, map[string]interface{}{"code": 0, "msg": "ok", "data": user})- 结构体需导出字段(首字母大写),否则序列化为空对象
{} - 若需控制时间格式(如去掉时区、用 YYYY-MM-DD),应在 struct 字段加
json:"created_at,string"tag 或自定义MarshalJSON()方法
ctx.StatusCode() + ctx.Write() 组合要慎用
手动控制状态码和响应体看似灵活,但极易遗漏关键细节。Iris 不会帮你补 Content-Type,也不会做 JSON 转义或编码校验。
容易踩的坑:
- 写了
ctx.StatusCode(400)却忘了ctx.Header("Content-Type", "application/json"),前端收到文本型响应,response.json()报错 - 用
fmt.Sprintf拼 JSON 字符串,遇到字段含双引号或换行就破坏结构,json.Unmarshal失败 - 未处理
nil指针字段,导致 panic(ctx.JSON()会安全转为null)
仅建议在极特殊场景使用,例如需要返回非标准 JSON 包裹格式(如外层固定 key:{"payload":{...}}),此时应封装成函数复用,并强制设置 header。
统一响应结构推荐用中间件 + 自定义方法
业务接口频繁返回 {"code":0,"msg":"success","data":{}} 这类结构,硬编码易出错且难维护。Iris 允许在 context.Context 上挂载方法,比全局函数更清晰。
实操建议:
- 在初始化 app 后,扩展 context:
app.Use(func(ctx iris.Context) { ctx.OnErrorCode(iris.StatusInternalServerError, func() { ctx.JSON(500, map[string]string{"code": "-1", "msg": "server error"}) }) ctx.Next() }) - 定义封装函数:
func (c *customCtx) Success(data interface{}) { c.JSON(200, map[string]interface{}{"code": 0, "msg": "ok", "data": data}) },再通过ctx.(customCtx).Success(user)调用 - 避免在每个 handler 里重复写 status/code/msg —— 中间件统一处理错误码映射,正常流走封装方法
注意 ctx.StopExecution() 对 JSON 响应的影响
如果在中间件中已调用 ctx.JSON(401, ...),必须紧跟 ctx.StopExecution(),否则后续 handler 仍会执行,可能造成重复写响应、panic 或数据污染。
典型错误:
- 鉴权中间件里写完
ctx.JSON(401, ...),末尾却还有ctx.Next()—— 请求继续进入业务 handler,可能查数据库、改状态,还再写一次响应 - 使用
ctx.StopExecution()后,ctx.JSON()依然有效;但若已调用过ctx.ResponseWriter().Write(),再调ctx.JSON()会 panic(HTTP header 已发送) - 调试时可用
ctx.IsStopped()判断是否已被中断,避免误操作
真正麻烦的不是怎么返回 JSON,而是响应时机——在哪儿写、写几次、写完是否该停,这三个点串起来才是 API 稳定的底线。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











