Nodejs技巧之----Joi数据校验

我们用nodejs实现一些功能时,往往需要对用户输入的数据进行验证。来保证用户输入的是否合规。那么是否有个库来帮我们来做这样的事情呢?
接下来就给大家介绍一个库---Joi

Joi文档

我总结了常用的一些方法,给大家分享出来,大家可以自行测试,好用才值得分享

第一部分 语法囊括与实例


// 通用类型登录
let paramSchema = Joi.object().keys({
    // 3 - 30 个 数字、字符
    username: Joi.string().alphanum().min(3).max(30).required(),
    // 3 - 30 位 字母数字组合密码
    password: Joi.string().regex(/^[a-zA-Z0-9]{3,30}$/),
    // string || number 都可以通过
    access_token: [Joi.string(), Joi.number()],
    // 生日限制
    birthyear: Joi.number().integer().min(1900).max(2018),
    // email 限制
    email: Joi.string().email(),
    // URI限制
    website: Joi.string().uri({
        scheme: [
            'git',
            /git\+https?/
        ]
    }),
    // ==== 允许为空/ 否认不允许为空 ====
    search: Joi.string().allow(''),
    // 验证枚举值,如果不传,默认为all 
    type: Joi.string().valid('disabled', 'normal', 'all').default('all'),
    // 开始时间 会自动格式化
    startTime: Joi.date().min('1-1-1974').max('now'),
    // 结束时间 必须大于开始时间,小于2100
    endTime: Joi.when(Joi.ref('startTime'), { is: Joi.date().required(), then: Joi.date().max('1-1-2100') }),
    // 页码 限制最小值
    page: Joi.number().integer().min(1).default(1),
    pageSize: Joi.number().integer().default(8),
    // 
    deleteWhenLtTen: Joi.number().integer().max(10).strip(),
    // 数组中包含某个字段 && 数字
    arrayString: Joi.array().items(
        // 数组中必须包含 name1
        Joi.string().label('name1').required(),
        // 数组中必须包含 数字
        Joi.number().required(),
        // 数组中可以包含其他类型,如bool, 但是最终结果会==除掉【以上类型的以外字段】
        Joi.any().strip()
    ),
    // 数组对象, 如需其参考以上字段
    arrayObject: Joi.array().items(
        Joi.object().keys({
            age: Joi.number().integer().max(200),
            sex: Joi.boolean()    
        })
    )
})
// with 中必须同时存在某些字段,故不可以填写一个参数
.with("username", "password")
// .without() 同理,不可以一个字段,不能同时存在
.without('a', 'b');




// 测试数据
const testData = {
    Password: "12345678"
}

// 验证
/**
 * 参数校验
 * @param {Object} checkInfo 要校验的对象
 * @param {Object} schema 参数校验
 * @param {Object} option 可选项
 * @param {Boolean} option.abortEarly: 设置 true,可以在检测到第一个错误时立即返回,默认 false(检查全部)。推荐设置 true
 * @param {Boolean} option.convert:设置 true,可以尝试将值转换为所需的类型(例如,将字符串转换为数字)。默认为 true。推荐采用默认
 * @param {Boolean} option.allowUnknown: 默认 false,则允许对象包含被忽略的未知键。默认为 false。推荐设置 true
 * @param {Boolean} option.skipFunctions:如果为 true,则忽略具有函数值的未知键。默认为 false。推荐采用默认
 * @param {Boolean} option.stripUnknown: 默认为 false,从对象和数组中删除未知的元素。默认为 false。也可以特殊的设置成 { objects: true , arrays: true }的形式,可以对象和数组分别处理。推荐采用默认
 * @param {String} option.presence: 设置默认的可选需求。支持的模式:’optional’,’required’,和 ’forbidden’。默认为 ’optional’。推荐采用默认
 * @param {Boolean} option.escapeHtml: 当为 true时,出于安全目的,错误消息模板将特殊字符转义为html实体。默认为 false。推荐采用默认
 * @param {Boolean} option.noDefaults:如果为 true,则不应用默认值。默认为 false。推荐采用默认
 */
const option = {
    allowUnknown: true, 
    abortEarly: true,
}
let value = Joi.validate(testData, paramSchema, option);

console.log(value);

if (value.error) {
    throw error;
}

第二部分 实战坑

2.1 验证结合后的规则

场景:如果每个接口都包含name/id等字段,那么我们需要重复写这两个规则么??
解决方案:必须的字段,统一管理,特殊的字段,特殊处理。
那么,如何对最后的scheme进行验证?

// 基础字段
const baseSchema = Joi.object(
     id: Joi.number().required(),
     name: Joi.string().required()
);
const schemaObj = {
     age: Joi.number().required(),
};

// 附加字段
let schema = baseSchema;
if (schemaObj) {
    schema = baseSchema.keys(schemaObj);
}
const option = {
    allowUnknown: true, 
    abortEarly: true,
}
const result = Joi.validate(ctx.request.body, schema, option);

Nodejs技巧之----Joi数据校验_第1张图片
326255-f67b0f0dd5fe5874.jpg

参考:
stackoverflow
joi 参数校验,过滤
欢迎关注IT实战联盟

你可能感兴趣的:(Nodejs技巧之----Joi数据校验)