Go后端返回JSON必须使用统一Resp结构体,含Code、Msg、Data、Timestamp字段;Content-Type需显式校验;文件上传用multipart/form-data;HTTP状态码与Resp.Code协同使用;CORS需白名单且Credentials需匹配Origin。

Go 后端返回 JSON 必须用统一结构体,不能直接 encode map
前端无法稳定解析裸 map[string]interface{} 或匿名 struct,字段缺失、类型错乱、嵌套层级不一致都会导致 JS 解析失败或静默丢数据。必须定义固定字段的响应结构体,例如:
type Resp struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data interface{} `json:"data"`
Timestamp int64 `json:"timestamp"`
}
-
Code用整数(0 表示成功,非 0 为业务错误码),不是 HTTP 状态码 -
Data允许为nil,但禁止传未导出字段、func、chan 等不可序列化类型 -
Timestamp用time.Now().UnixMilli(),别用time.Time或字符串格式 - 所有 handler 都调
c.JSON(200, Resp{...}),别在中间件里提前json.NewEncoder(w).Encode()
Gin 中处理 JSON 请求体前必须校验 Content-Type
c.ShouldBindJSON() 在请求头没带 Content-Type: application/json 时会静默返回空结构体,前端 400 错误但后端日志无提示,排查极难。
- 显式检查:
if c.Request.Header.Get("Content-Type") != "application/json" { writeError(c, 400, "INVALID_CONTENT_TYPE", "expect application/json", nil); return } - 再调
json.NewDecoder(c.Request.Body).Decode(&req),并检查解码 error - 禁止混用:URL query + JSON body;也别让前端用 GET 传数组或嵌套对象——Gin 默认不深层解析 query
- 文件上传必须用
multipart/form-data,且需先调c.Request.ParseMultipartForm()
HTTP 状态码和 resp.Code 必须协同,不能只靠一个判断
CDN 或反向代理可能重写 HTTP 状态码,前端仅靠 response.status === 401 做跳转不可靠;反过来,只看 data.code === 401 又会漏掉网络层错误。
前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。
- 未登录:设
w.WriteHeader(401)+Resp.Code = 401+Msg = "login required" - 权限不足:HTTP 状态码用
403,Resp.Code也填403 - 参数错误/业务异常:HTTP 状态码仍用
200,靠Resp.Code区分(如4001参数缺失、422校验失败) - 500 类错误必须带
Resp.Code = "INTERNAL_ERROR"(大写下划线风格),details字段生产环境要过滤堆栈和 DB 错误
CORS 配置必须区分开发与生产,且带凭证时 Origin 不能为 *
前端发带 Authorization 或 cookie 的请求,后端若只设 Access-Control-Allow-Origin: *,浏览器直接拒绝,控制台报 “The value of the 'Access-Control-Allow-Origin' header must not be the wildcard '*'”。
立即学习“go语言免费学习笔记(深入)”;
- 开发阶段可用
cors.AllowAll(),但上线前必须换成白名单:cors.AllowedOrigins([]string{"https://myapp.com", "https://admin.myapp.com"}) - 只要前端设了
credentials: true,后端就必须同时设:Access-Control-Allow-Credentials: true和具体 Origin -
Access-Control-Allow-Headers至少包含Authorization, Content-Type - 预检请求(OPTIONS)无需业务逻辑,但必须返回正确 header,Gin 可用
c.AbortWithStatus(204)
HTTPError 接口、每次跨域都得核对 Origin 白名单——这些动作没法靠中间件全自动兜底,漏一处,前端就多一个兼容补丁。

















