egg-validate 基于 parameter 的 eggjs 字段验证模块

egg-validate 是基于 parameter 的 eggjs 字段验证模块,可以验证我们日常开发中的大多数字段类型和数据,如果插件不满足你的需求,你还可以自定义验证规则。

egg-validate 基于 parameter 的 eggjs 字段验证模块

安装

npm install --save egg-validate

启用

// config/plugin.js

exports.validate = {

enable: true,

package: 'egg-validate',

};

配置

// config/config.default.js

exports.validate = {

// convert: false,

// validateRoot: false,

};

使用方法

egg-validate 就是对参数进行检验。比如检验一个用户名是不是字符串,可以这么写:

ctx.validate({ userName: 'string' });

默认就会对 ctx.request.body 进行检验,你想检验 ctx.query 的话,那就这样写:

ctx.validate({ userName: 'string' }, ctx.query);

params 就 ctx.params,它会在检验失败的抛出一个异常,没有捕获的话,会返回一个 422 错误。

第二种使用方法:

let errs = app.validator.validate({ userName: 'string' }, ctx.request.body);

ctx.validate 检验不通过会抛出异常,而 app.validator.validate 检验不通过会返回错误。你可以自己选择要对这个错误怎么处理,是停止执行还是返回前端。

完整的代码

// app/controller/home.js

const Controller = require('egg').Controller;

class HomeController extends Controller {

async index() {

const { ctx, app } = this;

ctx.validate({ id: 'id' }); // will throw if invalid

// or

const errors = app.validator.validate({ id: 'id' }, ctx.request.body);

}

}

module.exports = HomeController;

校验规则 rule

完全和 parameter 的校验规则一样。建议直接看readme文档,虽然是英文的,但是配着翻译看个7788是差不多的。

ctx.validate({ userName: 'string' });

这里面的rule就是{ userName: ‘string’ },它会这么检验,首先判断这个userName有没有在ctx.request.body里面,没有就跑出参数不存在、然后是userName不能为空、然后得是string。有一个不符合都会抛出错误。

你想判断一个用户的信息是否正确可以这么写:

ctx.validate({

userName: 'userName', // 自定义的校验规则

password: 'password', // 自带的校验规则

sex: ['men', 'women'], // 性别是 men 或者 women

age: {

type: 'number', // 年龄范围0-120

min: 0,

max: 120

}

});

这里有个坑,年龄怎么填都会报格式错误,这是因为配置的时候默认把参数转型关了,配置回来就好:

config.validate = {   // 配置参数校验器,基于parameter

convert: true, // 对参数可以使用 convertType 规则进行类型转换

// validateRoot: false, // 限制被验证值必须是一个对象。

};

使用自带的校验规则

password: 'password'

或者

password: {

type: 'password',

allowEmpty: true // 设置密码为空,作为示例乱写一下

}

校验规则有这些,文档很详细了:

  • 'int' => {type: 'int', required: true}
  • 'int?' => {type: 'int', required: false }
  • 'integer' => {type: 'integer', required: true}
  • 'number' => {type: 'number', required: true}
  • 'date' => {type: 'date', required: true}
  • 'dateTime' => {type: 'dateTime', required: true}
  • 'id' => {type: 'id', required: true}
  • 'boolean' => {type: 'boolean', required: true}
  • 'bool' => {type: 'bool', required: true}
  • 'string' => {type: 'string', required: true, allowEmpty: false}
  • 'string?' => {type: 'string', required: false, allowEmpty: true}
  • 'email' => {type: 'email', required: true, allowEmpty: false, format: EMAIL_RE}
  • 'password' => {type: 'password', required: true, allowEmpty: false, format: PASSWORD_RE, min: 6}
  • 'object' => {type: 'object', required: true}
  • 'array' => {type: 'array', required: true}
  • [1, 2] => {type: 'enum', values: [1, 2]}
  • /\d+/ => {type: 'string', required: true, allowEmpty: false, format: /\d+/}

自定义的校验规则

通过 app.validator.addRule 添加:

// 校验用户名是否正确

app.validator.addRule('userName', (rule, value)=>{ // value就是待检验的数据

if (/^\d+$/.test(value)) {

return "用户名应该是字符串";

}

else if (value.length < 3 || value.length > 10) {

console.log("用户名的长度应该在3-10之间");

}

});

这个可以直接放在 app.js 里面。return 的就是错误消息 message,但是 err 不止这个,还有错误字段啊啥的、都会帮我们自动包装好。

添加了这个规则就可以直接使用:

ctx.validate({userName: 'userName'});

或者这样使用:

ctx.validate({

userName: {

type: 'userName',

isAdmin: true'

},

});

直接赋值给 rule 传过来,然后你可以自己加判断,比如如果 isAdmin 的话,管理员用户名不能有中文啥的。

在哪里 addRule

上面写的是推荐大家在 app.js 里面 addRule,你可以在任何你能取到 app 的地方调用

app.validator.addRule('userName', (rule, value)=>{

去 addRule,但是不建议在 controller 里面 addRule。因为 controller 在每次路由匹配到之后都会进行实例化,所以请求了 n 遍,也就执行了这个 addRule n 遍。

而且代码会变的很臃肿,不易于管理。

在 app.js addRule 当然是很棒的,只在 app 加载时 add 一次。

但是问题又来了,随着 rule 变多,你在 app.js 里面写了很多代码都是关于 addRule 的,但是 app.js 又不止要写addRule,还写了一些别的,那看起来多乱啊。也不利于管理。

如何合理配置文件目录

我们希望能达到怎么样的一个效果呢?

  1. app.js 里面少写一些代码,最好就写一两行,做个配置这样子
  2. 对于所有的自定义校验规则独立出文件夹,取名 validate,放在 app/ 下面
  3. 针对相似的校验规则进一步抽象成文件,取名 user.js,放在 app/validate/ 下面
  4. 针对某一条特定的校验规则,如校验用户的 userName 放在 app/validate/user.js 里面
  5. 然后保持 egg-validate 的使用规则不变,原来是 ctx.validate 现在还是 ctx.vallidate。同时其他的插件、配置不受影响。

下面照着这几个目标实现代码

首先把 app.js 里面导入模块写出来

我们使用 Loader 来加载 validate 下面的所有文件:

const path = require('path');

module.exports = app => {

// 你的其它代码,balabala

// 加载所有的校验规则

const directory = path.join(app.config.baseDir, 'app/validate');

app.loader.loadToApp(directory, 'validate');

}

建立实际的校验规则文件

建立 app/validate/user.js 文件,写入以下代码

// app/validate/user.js

module.exports = app =>{

let { validator } = app;

// 校验用户名是否正确

validator.addRule('userName', (rule, value)=>{

console.log(rule);

if (/^\d+$/.test(value)) {

return "用户名应该是字符串";

}

else if (value.length < 3 || value.length > 10) {

console.log("用户名的长度应该在3-10之间");

}

});

// 添加自定义参数校验规则

validator.addRule('123', (rule, value) => {

if (value !== '123'){

return 'must be 123';

}

});

};

这里validator.addRule和原来一样,只是为了少写代码,之前把 validator 取出来了:

let { validator } = app;

之后需要再新建检验规则就写在 validate 里面,某一类相似校验规则要复用就直接拷贝文件就好了。

以上是 egg-validate 基于 parameter 的 eggjs 字段验证模块 的全部内容, 来源链接: utcz.com/p/232509.html

回到顶部