参数校验不是可有可无的事
你有没有遇到过用户输了个手机号,结果提交后系统直接报错崩溃?或者后台接口被人乱传数据,数据库里莫名其妙多了几条脏数据?这些问题背后,往往就是参数校验没做好。
在实际开发中,前端页面、API 接口、配置文件,到处都需要接收外部输入。这些输入就像门口进来的客人,不能啥人都放进去,得先看看证件——这就是参数校验的核心逻辑。
常见的校验场景
比如做一个注册功能,用户名不能为空,邮箱得符合格式,密码要满足长度和复杂度。如果跳过这些检查,轻则用户体验差,重则被恶意利用。
再比如调用第三方支付接口,金额字段必须是正数,订单号不能为空。一旦传了负数或空字符串,可能直接导致扣款失败甚至资金异常。
基础校验规则怎么写
以一个简单的用户信息提交为例:
const validateUser = (data) => {
if (!data.name || data.name.trim() === '') {
return { valid: false, message: '姓名不能为空' };
}
if (!/^[\w.-]+@[\w.-]+\.[a-zA-Z]{2,}$/.test(data.email)) {
return { valid: false, message: '邮箱格式不正确' };
}
if (data.age < 1 || data.age > 120) {
return { valid: false, message: '年龄必须在1到120之间' };
}
return { valid: true };
};这个函数对 name、email 和 age 做了基本判断。虽然看起来简单,但在很多小项目里已经够用了。
用现成工具更省心
自己写校验逻辑容易漏,维护也麻烦。现在主流框架都有成熟的校验方案。比如 Express 项目常用 joi,写起来像这样:
const Joi = require('joi');
const schema = Joi.object({
name: Joi.string().trim().min(2).max(20).required(),
email: Joi.string().email().required(),
age: Joi.number().integer().min(1).max(120).required()
});
const result = schema.validate(req.body);定义一次规则,后面直接复用。结构清晰,出错信息也友好。
前后端都要校验,但目的不同
前端校验是为了快速反馈,减少无效请求。比如用户输完邮箱马上提示格式不对,体验就好很多。但前端校验能被绕过,所以后端才是最后一道防线。
别听谁说“前端校验了后端就不用管”,这是典型的坑人说法。真正的生产环境,后端必须独立完成完整校验,不依赖任何前端结果。
动态规则怎么处理
有些场景校验规则会变。比如促销活动期间允许未成年人下单,平时不允许。这时候可以把规则抽出来做成配置:
const rules = {
allowUnderage: process.env.PROMOTION_ACTIVE === 'true'
};
if (!rules.allowUnderage && data.age < 18) {
return { valid: false, message: '未满18岁无法下单' };
}通过开关控制行为,上线下线都不用改代码。
错误提示要对用户友好
校验失败时别返回“invalid parameter”这种机器话术。用户看不懂,客服也头疼。应该明确告诉对方哪里错了,比如“手机号码格式不正确,请输入11位大陆手机号”。
对内日志可以详细些,记录原始参数和触发规则,方便排查问题。对外返回则要简洁准确,避免暴露系统细节。