Go中URL参数校验需早拦截、明规则、严转换:先ParseForm,再结构体映射+validator声明式校验,手写复杂逻辑,错误响应要明确安全。

在 Go 中做 URL 参数校验,核心是“早拦截、明规则、严转换”,不是等参数进到业务逻辑才检查,而是在请求进入 handler 的第一时间,就完成类型解析 + 业务规则验证。
用 net/url 解析并提取原始参数
别直接用 r.URL.Query() 拿 map 后手动转类型——它会把所有值都当字符串,且忽略重复键、空值等边界情况。应先用 url.ParseQuery(r.URL.RawQuery) 或更稳妥地用 r.ParseForm()(自动处理 POST 表单和 URL 查询),再逐个取值校验。
- 注意空字符串、"null"、"undefined" 等伪空值需主动识别
- 对多值参数(如
?tag=a&tag=b),用r.Form["tag"]获取切片,而非r.FormValue("tag")(只取第一个)
定义结构体 + 使用 validator 库统一校验
把 URL 参数映射为结构体字段,配合 go-playground/validator/v10 做声明式校验,清晰又可复用。例如:
type ListRequest struct {
Page int `form:"page" validate:"required,min=1,max=1000"`
Size int `form:"size" validate:"required,min=1,max=100"`
Category string `form:"category" validate:"omitempty,oneof=tech news video"`
Keyword string `form:"keyword" validate:"max=50"`
}
在 handler 中:
立即学习“go语言免费学习笔记(深入)”;
- 调用
r.ParseForm()后,用decoder.Decode(&req, r.Form)(推荐go-macaron/binding或自写简易 decoder)填值 - 立即执行
validate.Struct(req),校验失败则返回 400 和具体错误字段 - 对数字类字段,
validate会自动尝试字符串转 int/float,失败即报错,无需额外strconv
关键业务规则必须手写逻辑,不能只靠 tag
结构体 tag 能覆盖基础规则(非空、范围、枚举),但复杂逻辑仍需代码判断。例如:
- 时间范围参数
start_time和end_time需互相比对:if req.EndTime.Before(req.StartTime) { ... } - ID 类参数需校验是否为合法 UUID 或符合项目约定的格式(如纯数字、固定长度)
- 敏感字段(如
user_id)要结合 JWT 或 session 校验是否属于当前用户,防止越权
错误响应要明确、安全、不泄密
校验失败时,避免返回模糊提示(如“参数错误”)或暴露内部结构(如 “invalid type for field size”)。建议:










