输入校验的四层:格式、范围、关系与权限
舒心读
18
卷中目录
一个表单“看起来填对了”,不代表它可以直接进入业务处理。请求还可能来自旧页面、脚本、重复提交,甚至完全不同的客户端。入口边界需要一套清楚、可重复的检查。
本篇目标: 用格式、范围、关系和权限四层检查,把模糊的“参数不对”变成可以定位的问题。

第一层,确认类型与结构
先明确字段是否存在、是什么类型,集合里允许哪些元素。不要让字符串、数字和布尔值在不同分支里随意互相转换。例如字符串 "false" 在 JavaScript 条件判断中仍是真值,直接用 Boolean(value) 可能得到与输入者意图不同的结果。
对不接受的字段采用明确策略:拒绝或忽略,并保持一致。更新接口最好列出允许修改的字段,避免把整个输入对象直接合并进内部对象。
第二层,限制合理范围
以查询参数 limit 为例,它最初是文本,应先检查文本形式,再转成数字,而不是先做宽松解析。
function parseLimit(raw = '20') {
if (!/^[1-9]\d{0,2}$/.test(raw)) throw new Error('limit 格式不正确');
const value = Number(raw);
if (value > 100) throw new Error('limit 不能超过 100');
return value;
}
该示例有意拒绝小数、负数和带额外字符的值。边界数字是演示选择,应根据接口容量调整。
第三层,检查字段之间的关系
开始时间和结束时间各自合法,组合起来仍可能出现开始晚于结束。一个可选字段启用后,也可能要求另一个字段必须提供。这些关系规则应在服务端集中维护,减少多个客户端各写一套后逐渐偏离。
第四层,检查操作权限
输入中的对象标识不代表访问授权。用户是否能读取、修改或删除这个对象,需要结合当前身份和对象归属判断。格式合法与权限允许,是两件不同的事。
错误响应可以返回字段名、错误类型和可理解的说明,同时避免包含内部堆栈或无关对象信息。测试时至少覆盖缺失值、空值、边界值、额外字段、组合冲突和越权引用;前端校验则负责尽早给用户同样清楚的提示。
见字如晤