url.ParseRequestURI 是最轻量且最贴近 RFC 3986 的 URL 合法性校验方式,仅做语法解析不发请求,返回 nil 表示合法;它要求绝对 URI,故 "example.com" 或 "http://" 均非法,空值需配合 required 标签才能触发校验。

用 url.ParseRequestURI 校验 URL 字符串是否合法
它是最轻量、最贴近 RFC 3986 的方式,不发请求、只做语法解析。返回 nil 表示合法,否则非法。
常见踩坑点:
-
"example.com"或"http://"都会失败——前者缺 scheme,后者缺 host -
url.ParseRequestURI要求绝对 URI,相对路径(如/api/v1)必须用url.Parse - 空字符串、
nil、未赋值字段不会触发校验,validator.v9的urltag 默认跳过零值,得配required:validate:"required,url" - 如果业务允许用户省略
https://,得先预处理补全,再校验;不能直接把原始输入扔给ParseRequestURI
struct tag 里用 expr 做运行前配置校验
Go-Spring 等框架支持在字段上写 expr 标签,表达式里的 $ 是已转成 Go 类型的值,不是原始字符串。
这样能直接基于业务语义写规则,比如:
立即学习“go语言免费学习笔记(深入)”;
- 端口:
expr:"$ > 0 && $ —— <code>$是int,不用再strconv.Atoi - 日志级别:
expr:"$ in ['debug', 'info', 'warn', 'error']"——$是string,天然支持枚举校验 - 超时时间:
expr:"$ >= duration(\"1s\")"——$是time.Duration,可直接比大小
注意:表达式必须返回 bool;校验失败会导致启动阶段 panic,而不是等运行时暴露为连接失败或超时异常。
用 json.Unmarshal 校验 JSON 字符串或文件内容
这是验证 JSON 合法性的唯一可靠方式,json.Valid 只检查字节流结构,不保证可解码;而 Unmarshal 才真正走完整解析流程。
实操要点:
- 对字符串校验:直接
json.Unmarshal([]byte(s), &v),err 非 nil 即非法 - 对文件校验:先
os.ReadFile,再Unmarshal;别跳过读取错误,io.EOF或权限问题也会导致后续误判 - 若需格式化输出,用
json.MarshalIndent,但仅限校验通过后——别在校验失败路径里调用它,可能 panic - 不要用正则匹配
{...}或[...]来“快速判断”,RFC 允许注释外空白、Unicode 转义、嵌套结构,正则根本不可靠
文件名合法性校验要分层处理
文件名不是纯语法问题,得按使用场景拆解约束:
- 基础字符限制:用正则
^[a-zA-Z0-9._-]{1,255}$拦住控制字符、斜杠、空字符等危险符号 - 保留名拦截(Windows):需显式检查
"CON"、"PRN"、"AUX"等(忽略大小写),strings.EqualFold比较 - 长度限制:OS 层面有差异,Linux ext4 单文件名上限 255 字节,Windows NTFS 是 255 UTF-16 code units,用
utf8.RuneCountInString更准 - 路径安全:仅校验文件名不够,
../../etc/passwd这种路径遍历得靠filepath.Clean+strings.HasPrefix检查是否仍在白名单目录内
所有校验都应在写入磁盘前完成,别依赖 OS 返回的 invalid argument 错误来兜底——那已经是最后一道防线,且错误信息模糊,不利于调试。


















