菜单

JSON 响应

相关源文件

此页面介绍了 Gin 框架中的 JSON 响应机制。JSON 是一种常见的 API 响应格式,Gin 提供了多种专门的方法,用于以不同的格式选项、安全考虑和内容处理行为将数据渲染为 JSON。

有关 HTML、XML、YAML 或 TOML 等其他响应格式的信息,请参阅 其他响应格式

JSON 响应概述

Gin 提供了多种返回 JSON 响应的方法,每种方法都针对特定的用例进行了设计

方法目的Content-Type
JSON()标准 JSON 序列化application/json; charset=utf-8
IndentedJSON()带缩进的格式化 JSONapplication/json; charset=utf-8
SecureJSON()防止 JSON 劫持application/json; charset=utf-8
JSONP()支持跨域请求application/javascript; charset=utf-8
AsciiJSON()将非 ASCII 字符转换为 \uXXXX 序列application/json
PureJSON()禁用 HTML 转义application/json; charset=utf-8
AbortWithStatusJSON()结合 abort 和 JSON 响应application/json; charset=utf-8

来源:context.go1097-1111 render/json.go17-47

JSON 响应架构

Gin 中的 JSON 响应系统主要由两个组件组成

  1. Context 方法 - 用于生成 JSON 响应的用户界面 API
  2. Render 类型 - 处理 JSON 序列化的内部实现

来源:context.go1097-1111 render/json.go17-47 render/render.go9-15

基本 JSON 响应

返回 JSON 最常用的方法是 c.JSON(),它会将任何 Go 数据结构序列化为 JSON,并设置适当的 Content-Type 标头。

来源:context.go1097-1098 render/json.go56-63

JSON 方法说明

标准 JSON 响应

JSON() 方法是返回 JSON 数据最常用的方法。它会将提供的数据结构序列化为 JSON,并为安全起见转义 HTML 字符。

c.JSON(http.StatusOK, gin.H{"message": "success", "data": user})

来源:context.go1097-1099 render/json.go56-63

格式化 JSON 响应

IndentedJSON() 方法使用缩进和换行符格式化 JSON 输出,使其更易于调试。但是,它会占用更多带宽和处理能力。

c.IndentedJSON(http.StatusOK, gin.H{"message": "success", "data": user})

来源:context.go1072-1074 render/json.go77-85

安全 JSON 响应

SecureJSON() 方法会在数组响应前加上一个字符串,以防止 JSON 劫持攻击。在返回敏感数据作为 JSON 数组时,这一点很重要。

c.SecureJSON(http.StatusOK, []string{"sensitive", "data"})

来源:context.go1079-1081 render/json.go93-108

JSONP 响应

JSONP() 方法将 JSON 响应包装在回调函数中,允许跨域请求。如果未指定回调,则会回退到常规 JSON。

c.JSONP(http.StatusOK, gin.H{"message": "success"})
// With callback parameter "?callback=callbackName"

来源:context.go1086-1093 render/json.go116-146

ASCII JSON 响应

AsciiJSON() 方法将非 ASCII 字符转换为其 Unicode 转义序列(\uXXXX)。这确保输出只包含 ASCII 字符。

c.AsciiJSON(http.StatusOK, gin.H{"message": "你好"})
// Output: {"message":"\u4f60\u597d"}

来源:context.go1103-1105 render/json.go154-172

纯 JSON 响应

PureJSON() 方法禁用 HTML 转义,直接渲染 JSON。这在需要将 HTML 包含在 JSON 响应中时很有用。

c.PureJSON(http.StatusOK, gin.H{"message": "<b>Hello</b>"})
// Output: {"message":"<b>Hello</b>"}

来源:context.go1109-1111 render/json.go180-185

带错误处理的 JSON

AbortWithStatusJSON() 方法结合了两个操作:它会中止请求处理链并返回 JSON 响应。这通常用于错误响应。

c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})

来源:context.go221-224

选择正确的 JSON 方法

在决定使用哪种 JSON 响应方法时,请考虑以下因素

来源:context.go1072-1111

性能考量

  1. 标准 JSON 与格式化 JSONIndentedJSON() 会产生更大的响应并消耗更多 CPU 时间。在生产环境中应避免使用。

  2. 内容协商:当 HTTP 状态码为 204 No Content 时,即使 Content-Type 标头仍然设置,响应正文也不会发送。此行为是在 bodyAllowedForStatus() 函数中实现的。

  3. 内存分配:JSON 序列化过程会为序列化数据分配内存。对于大型对象,这可能会影响性能。

来源:context.go964-975 render/json.go66-74

最佳实践

  1. 简单响应使用 gin.Hgin.H 类型(map[string]interface{} 的别名)对于动态构建 JSON 对象很方便。

  2. 考虑响应大小:对于大型数据集,请考虑分页或流式响应,以避免过多的内存使用。

  3. 错误处理:对错误响应使用 AbortWithStatusJSON(),以确保不再执行后续的 handler。

  4. 安全:返回带有敏感数据的数组时,请使用 SecureJSON() 以防止 JSON 劫持攻击。

  5. 测试:在测试期间检查您的 JSON 响应,以确保它们具有预期的结构和 Content-Type。

来源:context.go221-224 context.go1079-1081

常见用例

标准 API 响应

c.JSON(http.StatusOK, gin.H{
    "status": "success",
    "data": result,
})

错误响应

c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
    "status": "error",
    "message": "Invalid request parameters",
})

序列化结构体

type User struct {
    ID    string `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email,omitempty"`
}

c.JSON(http.StatusOK, User{
    ID:    "123",
    Name:  "John Doe",
    Email: "john@example.com",
})

来源:context.go1097-1098 context.go221-224