joi:nodejs服务端(表单)数据校验模块
简介
joi是一个强大的数据校验模块,可以对数据进行格式和数据类型上的校验,支持正则表达式,功能非常强大,可以很方便地在后端对客户端返回的表单数据进行校验。
ps:浏览器端提交的表单数据,可能跳过了前端js的验证(禁用浏览器的js),或者用其它软件访问注册用户的地址,把任意数据提交到服务器。所以在服务器端对表单数据进行再次校验是很有必要的。如果在后端进行手写验证规则,验证的字段可能会很多,像用户名、邮箱等都得考虑,会使得本来就很复杂的业务代码变得更繁琐,所以joi的价值就体现出来了
api介绍:joi v17.4.0
ps:官方文档都是英文,这个博客可能可以帮助你更容易理解官方文档
使用
-
项目目录下,下载joi模块
npm i joi -S
-
导入模块
const Joi = require('joi')
-
定义验证规则
ps:在表述上,下面把对象的属性称为字段了
// Joi.object()的方法,接收一个对象作为参数 // 这里定义的规则可以验证一个新用户的注册表单数据 const userDateRules = Joi.object({ nickName: Joi.string().min(6).max(16).required().error(new Error('用户名不符合验证规则')), email: Joi.string().regex(/^[A-Za-z\d]+([-_.][A-Za-z\d]+)*@([A-Za-z\d]+[-.])+[A-Za-z\d]{2,4}$/).required().error(new Error('邮箱不符合验证规则')), password: Joi.string().required().regex(/^[a-zA-Z0-9]{3,30}$/).error(new Error('密码不符合验证规则')), status: Joi.number().valid(0, 1), role: Joi.string().valid('normal', 'admin') }) }
-
验证具体数据
上一步执行后,会返回一个对象,该对象下的validate方法可以用来校验具体的数据
// 这里先准备一个被验证的数据 // userData中的各字段名和验证规则中的字段名相同时,才会对该字段进行校验(不要求顺序) // 比如userData中的status: 1,对应上一步中的校验规则是status: Joi.number().valid(0, 1) const userDataObj = { nickName: 'greaclar', email: 'greaclar@china.cn', password: '123456789', role: 'admin', avatar: null, createTime: new Date, status: 1 } // validate方法接收两个参数 // 第一个是要被验证的数据 // 第二个参数是可选的,用来定义进行校验时的一些行为 // 如:是否允许被校验的数据中,包含没有匹配校验规则的字段,这里的userDataObj包含avatar字段而校验规则中并没有该字段 const result = userDateRules.validate(userData, { // false:表示对所有字段进行校验错误;如果不定义,只要发现不合法的字段就会停止校验 abortEarly: false, // 允许验证被对象包含没有定义校验规则的未知字段,否则会认为被校验数据不通过 allowUnknown: true })
-
接收验证结果
// 上一步执行后,result变量将接收一个对象 // 如果被校验数据中,包含不符合校验规则的字段,result会包含一个error属性,包含错误信息 // 校验通过error将会是undefined const { error } = result if(error) { // 如果nickName字段不符合规则将输出: // 用户名不符合验证规则 console.log(error.mssage) } else { console.log('校验通过了,新用户将被创建') }
完整代码
const Joi = require('joi')
const validateUser = user => {
return Joi.object({
nickName: Joi.string().min(6).max(30).required().error(new Error('用户名不符合验证规则')),
email: Joi.string().regex(/^[A-Za-z\d]+([-_.][A-Za-z\d]+)*@([A-Za-z\d]+[-.])+[A-Za-z\d]{2,4}$/).required().error(new Error('邮箱不符合验证规则')),
password: Joi.string().required().regex(/^[a-zA-Z0-9]{3,30}$/).error(new Error('密码不符合验证规则')),
status: Joi.number().valid(0, 1),
role: Joi.string().valid('normal', 'admin')
})
.validate(user, {
abortEarly: false,
allowUnknown: true
})
}