Gin 的 c.JSON() 默认不支持折叠渲染,因其底层调用 json.Marshal() 输出紧凑格式(无空格、无换行),旨在生产环境追求体积小、序列化快;需改用 json.MarshalIndent() 配合 c.Data() 手动返回缩进 JSON,并确保 Content-Type 正确且无前置非法字符。

为什么 Gin 的 c.JSON() 默认不支持折叠渲染
Gin 的 c.JSON() 底层调用 json.Marshal(),输出的是紧凑格式(无空格、无换行),浏览器或 curl 看到的是一长串密文,没法展开/折叠。这不是 bug,是设计使然——生产环境默认追求体积小、序列化快。
要实现“可折叠 JSON”,本质是返回带缩进的格式化 JSON,并确保响应头 Content-Type 正确,且前端(如浏览器 DevTools 或 Postman)能识别为 JSON 并启用语法高亮与交互式折叠。
- 必须设置
Content-Type: application/json; charset=utf-8(Gin 默认已设) - 必须用缩进(如 2 空格)序列化,不能依赖前端自动美化(它不会自动格式化紧凑 JSON)
- 避免在生产环境无条件开启——格式化有 CPU 开销,且可能暴露结构细节
用 json.MarshalIndent() 手动替换 c.JSON()
最直接可控的方式:绕过 c.JSON(),自己序列化再写入响应体。注意别漏掉状态码和 header 设置。
data := map[string]interface{}{"user": map[string]string{"name": "alice", "role": "admin"}}
b, _ := json.MarshalIndent(data, "", " ") // 第二个参数是 prefix,第三个是 indent
c.Data(200, "application/json; charset=utf-8", b)
-
json.MarshalIndent()的第二个参数(prefix)通常传"";第三个参数(indent)建议用" "(两个空格),和主流编辑器/DevTools 默认一致 - 不要用
c.String()替代——它会把Content-Type设成text/plain,导致浏览器不触发 JSON 折叠 - 如果结构体字段含非导出字段(小写首字母),
json.MarshalIndent()同样不会序列化,和c.JSON()行为一致
开发环境自动启用缩进:加个中间件判断 GIN_MODE
没必要改所有 handler,可以在全局加一层轻量中间件,只在 debug 模式下启用格式化。
立即学习“go语言免费学习笔记(深入)”;
func PrettyJSON(c *gin.Context) {
if gin.Mode() == gin.DebugMode {
c.Header("Content-Type", "application/json; charset=utf-8")
c.Next() // 先执行后续 handler,假设它把 data 放到了 c.Keys
if data, ok := c.Get("response_data"); ok {
b, _ := json.MarshalIndent(data, "", " ")
c.Status(200)
c.Writer.Write(b)
c.Abort()
return
}
}
c.Next()
}
- 这个中间件需放在
c.Set("response_data", ...)的 handler 之后,比如在业务 handler 里写c.Set("response_data", result) - 更稳妥的做法是封装一个
c.PrettyJSON(code int, obj interface{})方法(通过gin.Engine().RouterGroup.AddMiddleware()不支持方法扩展,得靠自定义*gin.Context子类或工具函数) - 注意:Gin 的
c.JSON()内部会调用c.Render(),而c.Render()会清空已写 header —— 所以手动写c.Writer.Write()前务必不再调用任何c.JSON()或c.Render()
Postman / curl 查看时仍不折叠?检查这三点
即使后端返回了缩进 JSON,前端也可能不折叠,常见原因很具体:
- 响应头缺失
Content-Type: application/json(哪怕只差个分号或空格,Chrome DevTools 就当 text) - 响应体开头有不可见字符(比如 BOM、前置日志打印、panic 恢复后残留的 panic msg)——用
curl -v看 raw response body 是否以{或[开头 - Postman 中点了 “Pretty” 标签但显示 “Could not format JSON”,大概率是 JSON 本身语法错误(比如多逗号、单引号、末尾逗号),
json.MarshalIndent()不会出错,但手写的 map 或 struct 可能含非法值(如NaN,infinity)
调试时优先用 curl -s -H "Accept: application/json" http://localhost:8080/api | python3 -m json.tool 验证——它不依赖 header,只认内容是否合法 JSON。


















