--- tags: [后端, Go, Gin, 响应渲染, JSON] create time: 2026-04-28 00:00 --- # 响应渲染 ## 概述 Gin 提供了丰富的响应渲染方法——不仅是基础的 JSON 返回,还包括防劫持的 SecureJSON、保留中文的 PureJSON、ASCII 转换、XML/YAML/ProtoBuf 输出等。理解各渲染方法的差异和适用场景,能写出更健壮、兼容的 API。 思考题:为什么 Gin 要同时提供 `JSON` 和 `PureJSON`?它们什么时候输出相同的结果,什么时候不同? ## 正文 ### 1. 标准 JSON 渲染 ```go func handler(c *gin.Context) { data := gin.H{ "message": "你好", "items": []string{"a", "b", "c"}, } // 等价于 c.Render(200, render.JSON{Data: data}) c.JSON(http.StatusOK, data) } ``` 输出: ```json {"items":["a","b","c"],"message":"你好"} ``` **注意:** 标准 `c.JSON()` 会对非 ASCII 字符做 Unicode 转义(`\uXXXX`),这是 RFC 4627 的要求,但现代浏览器和客户端都无需此限制。 ### 2. PureJSON — 保留原始 Unicode ```go func handler(c *gin.Context) { c.PureJSON(http.StatusOK, gin.H{ "message": "你好世界", }) } ``` 输出: ```json {"message":"你好世界"} ``` **`PureJSON` vs `JSON` 对比:** | 特性 | `c.JSON()` | `c.PureJSON()` | |------|-----------|----------------| | 中文编码 | `你好` | `你好` | | HTML 转义 | ` ``` > **安全警告:** JSONP 要求回调函数名白名单校验,否则攻击者可构造 `callback=` 注入 XSS。 ### 7. 渲染方法速查 | 方法 | 内容类型 | 特点 | |------|----------|------| | `c.JSON(code, obj)` | `application/json` | 标准 JSON,ASCII 转义 | | `c.PureJSON(code, obj)` | `application/json` | 保留原始 Unicode | | `c.SecureJSON(code, obj)` | `application/json` | 加前缀防劫持 | | `c.AsciiJSON(code, obj)` | `application/json` | 强制 ASCII 编码 | | `c.XML(code, obj)` | `application/xml` | XML 序列化 | | `c.YAML(code, obj)` | `application/x-yaml` | YAML 序列化 | | `c.ProtoBuf(code, obj)` | `application/x-protobuf` | Protobuf 序列化 | | `c.String(code, format, vals)` | `text/plain` | 字符串格式化 | | `c.Data(code, data)` | 自定义 | 原始字节流 | | `c.HTML(code, tmplName, obj)` | `text/html` | HTML 模板渲染 | 思考题:如果你的 API 同时需要提供 JSON 和 CSV 两种格式,Gin 本身没有 `c.CSV()`,你应该怎么做? 提示:`c.Data()` 和 `c.Writer.Write()` 的组合。