Iris 不会自动设置 HTTP 状态码,必须显式调用 ctx.StatusCode() 或在 ctx.JSON(status, v) 中传入状态码;省略 200 会导致业务错误被掩盖为成功响应,破坏前端错误处理、中间件触发及文档生成。

必须显式调用 ctx.StatusCode() 或在 ctx.JSON() 中传入状态码,Iris 不会根据结构体字段或返回值自动设 HTTP 状态码。
为什么 ctx.JSON(200, data) 里的 200 不能省略
Iris 的 ctx.JSON() 默认不设状态码,只序列化数据并写入响应体。不传第一个参数时,它默认用 iris.StatusOK(即 200),但这个“默认”容易掩盖逻辑错误:
- 业务上应返回 400 却忘了传码,结果前端收到 200 + 错误结构体,fetch().then() 仍会进成功分支
- 统一响应结构体里有
Code字段(如{"code": 40001}),但这和 HTTP 状态码完全无关,前端靠response.status判断成败,不是靠 JSON 里的code - 中间件或
OnErrorCode钩子依赖真实状态码触发,若没设对,这些机制就失效
ctx.StatusCode() 和 ctx.JSON(status, v) 怎么选
两者效果等价,但语义和使用场景不同:
- 需要返回空响应(如 204 No Content)或纯文本(如 401 Unauthorized)时,用
ctx.StatusCode(401); ctx.WriteString("Unauthorized") - 返回 JSON 且结构固定时,优先用
ctx.JSON(400, Response{Code: 40001, Message: "xxx"}),避免漏掉Content-Type头 - 不要混用:先调
ctx.StatusCode(400)再调ctx.JSON(200, ...)—— 后者会覆盖前者,最终仍是 200 - 错误响应别只设状态码不写体:
ctx.StatusCode(400)后没调ctx.JSON()或ctx.WriteString(),客户端可能收不到任何 body
4xx/5xx 错误响应怎么避免状态码和 JSON 脱节
常见错误是 handler 里 panic 了、校验失败了,但只返回 Response{Code: 40001} 而没设对应 HTTP 状态码,导致返回 200 + 错误 JSON:
- 所有业务错误路径,必须同时控制状态码和响应体,例如:
ctx.JSON(400, Response{Code: 40001, Message: "missing id"}) - 全局 recover 中间件中,
iris.Recover默认返回 500 + 纯文本,若要返回 JSON,需传自定义函数:iris.Recover(func(ctx iris.Context, err interface{}) { ctx.JSON(500, Response{Code: 50000, Message: "server error"}) }) - 用
app.OnErrorCode(iris.StatusNotFound, ...)拦截 404 时,handler 内仍需显式调ctx.StatusCode(404)才能触发该钩子
状态码和前端协作的关键细节
HTTP 状态码不是装饰,它是浏览器和 fetch/fetch-like 库的执行分水岭:
-
fetch("/api/user").then(res => { console.log(res.status) })—— 这里的res.status来自ctx.StatusCode(),不是 JSON 字段 - 只有 2xx 状态码才会进
.then(),4xx/5xx 会进.catch(),所以前端不会看到{"code": 40001}就自动报错,得靠状态码驱动流程 - Swagger/OpenAPI 文档生成依赖实际返回的状态码,若 handler 里没写
ctx.JSON(401, ...),文档里就只标了 200 成功路径
最容易被忽略的是:状态码一旦由 ctx.JSON() 或 ctx.StatusCode() 写出,就不可再改;后续中间件再调 ctx.StatusCode() 无效。所以务必在真正决定响应类型(成功/失败)的那一刻,就把状态码和 body 一起定下来。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











