学习目标:
一、引言
不管是在公司做开发还是做个人项目的时候,我们大都会看到数据验证的影子,无论是在前端还是后端都要对同样的数据进行一次完整的验证,因为我们要保证数据的完整性、有效性……等,这样就有利于我们的后期开发。
二、数据校验
1、原因和目的
首先,互联网是非常之大的,那么我们可以将网络看作是一片汪洋大海,而数据在网络中传输,就相当于一滴水融入了大海,那么我们要想再完整的取出这一滴水是非常困难的,因为我们不知道数据在网络中传输会变成什么样子,有可能是字符串,也有可能是数字……等,所用为了解决这样的问题,我们必须使用数据验证。
就像正则表达式一样,我们要设置一定的规则,将不符合规则的数据过滤掉,拿出符合规则的数据,那么这样我们就可以拿到我们想要的数据
2、如何进行数据验证
-
分支语句
JavaScript 分支语句包括
if...else
和switch
分支语句,在项目中使用分支语句也是可以的,但是我不建议大家使用这样原生的方法,因为这样构思的代码太繁琐、不好管理、不易看懂、多次嵌套可能出现一些小问题,代码重用性不好,不适合大量的验证,扩展性不好。 -
第三方包
在Node.js下安装表单数据验证的第三方包来对我们的数据进行一定的验证,这样做代码重用性高、利于管理和修改、代码简单易懂,可扩展性高。
三、@hapi/joi
1、介绍
@hapi/joi 是Node.js最强大的 JavaScript 模式描述语言和数据的一个验证器,可以对数据进行一定的规则验证,是一个简单、简简洁、易懂、易上手的数据验证第三方包。
2、使用
- Node环境下下载
@hapi/joi
包
npm install @hapi/joi
- 导入
@hapi/joi
const joi = require("@hapi/joi");
- 定义带有验证规则的对象
// 定义对象的验证规则
const schema = {
/*
属性1:验证规则1,
属性2:验证规则2,
......
*/
};
//示例:
const schema = {
// 该属性的值为字符串类型,长度为2-5之间,不为空,如果不符合规则,则抛出“请输入正确规则的username”的异常
username: Joi.string().min(2).max(5).required().error(new Error('请输入正确规则的username')),
// 该属性的值为数字类型,值只能为1998-2020之间,如果不符合规则,则抛出“请输入正确规则的birth”的异常
birth: Joi.number().min(1998).max(2020).error(new Error('请输入正确规则的birth'))
};
- 进行数据验证
// 向外部共享一个接口
// data:要验证的数据对象
module.exports = function(data) {
// 通过解构,拿到错误信息字符串error
// var {异常字符串,值}= 验证规则对象.validate(要验证的数据);
var { error, value } = schema.validate(data);
// error :异常字符串,value:值
// 如果异常信息字符串不为空,则证明抛出了异常信息
if (error) {
// 就返回异常信息
return error;
}
// 否则返回空
return null;
};
3、API方法介绍
.string()
:数据必须为字符串类型.number()
:数据必须为数字类型.integer()
:数据必须为整数类型.alphanum()
:数据只能包含[a-zA-Z0-9]的字符.max(number|string)
:number:最大长度 | string:最大日期.min(number|string)
:number:最小长度 | string:最小日期.required()
:数据为必填项,不能为null或undefined.pattern(正则表达式)
:以正则表达式的形式验证数据.regex(正则表达式)
:定义字段必须匹配正则规则。.email()
:验证邮箱.joi.ref(key:string)
:引言同辈的键值,就是拿到value.not(values:any[])
:当前属性的值不能同参数值相同.valid(...values:any[])
:当前属性的值必须于参数值相同.dataUri()
:当前字段为可以是URL地址.allow(...values:any[])
:该字段允许为指定参数的值.default(any[])
:设置该字段的默认值,值可以为string、number、boolean……等
4、模块优化
// 导入数据验证的模块
const joi = require("@hapi/joi");
// 定义验证规则对象
const 对象名称 = joi.object({
// 验证规则
// key:value
});
// 向外公布验证规则对象
module.exports.schema = {
// key:value
// 键值:上面定义的验证规则对象
};
// 公开验证接口
module.exports.validate = function(data, schema) {
// 通过解构拿到异常字符串
let { error, value } = schema.validate(data);
// 如果异常字符串不为空
if (error) {
// 则返回异常字符串
return error;
}
// 否则返回null
return null;
};
/*
参数说明:
1. data:要验证的对象
2. schema:选择验证规则对象
*/
四、常用数据验证规则对象
1、修改密码
// 判断的验证规则,新密码不能与旧密码一致
const schemapwd = joi.object({
// 旧密码:字符串,最小长度6,最大18,不为空
oldpwd: joi.string().min(6).max(18).required().error(new Error("密码为6-18位任意字符!")),
// 新密码:不能与旧密码的值相同
newpwd: joi.not(joi.ref("oldpwd")).error(new Error("新密码不能和旧密码相同!")),
// 重复密码:类型任意,不能为空,校验规则:必须和新密码相同
aginpwd: joi.any().required().valid(joi.ref("newpwd")).error(new Error("重复密码和新密码不一致!")),
});
2、登录验证
const schema = joi.object({
// 账号
ulogid: joi.string().required().alphanum().min(6).max(11).error(new Error("输入登录账号格式有误!")),
// 密码
upwd: joi.string().required().min(6).max(18).error(new Error("用户密码为6-18位任意字符"))
});
3、注册验证
const schema = joi.object({
// 用户名
uname: joi.string().required().error(new Error("用户名格式有误!")),
// 邮箱
uemail: joi.string().required().pattern(/^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/).error(new Error("邮箱格式有误!")),
// 账号
ulogid: joi.string().required().alphanum().min(6).max(11).error(new Error("账号格式有误!")),
// 密码
upwd: joi.string().required().min(6).max(18).error(new Error("用户密码为6-18位任意字符")),
});
4、路径/url地址/base64编码
const schemaavatar = joi.object({
avatar: joi.string().dataUri().required().error(new Error("请选择图像!"))
});
5、排序验证
const page = joi.object({
sort: joi.string().required().default("asc").allow("asc").allow("desc").error(new Error("排序格式有误!"))
});
五、总结
以上均为@hapi/joi第三方包的基本使用,当然使用方式还很多,需要大家去不断探索学习。希望大家牢记一句话:“不管做后端还是前端我们都需要对数据负责,所以后端不能相信前端传入的数据,必须要进行数据验证”。当前前端数据验证可以使用layui框架,这个框架做前端数据验证是非常好用的,大家下取可以去学习。
传送门: