【Express.js】express-validator

express-validator

express.js 集成 express-validator进行数据校验

在最初的时候,对于请求的数据校验,我们是自定义一个中间件,然后在里面通过最原生的方式检验。在本节,我们将尝试用一种更优雅的方式进行数据校验。

准备工作

创建一个基础的 express 项目(本文基于evp-express-cli),并支持全局同步和异步错误错误处理。

安装express-validator,并引入:

console 复制代码
npm i express-validator
js 复制代码
const validator = require('express-validator');

验证链

validator:

  • body()
  • cookie()
  • header()
  • param()
  • query()

validator.query为例,我们可以检查query参数中的某一项

js 复制代码
router.get('/greet', 
	validator.query('person').trim().notEmpty().escape().withMessage("person不能为空"),
(req, res, next) => {
  const valires = validator.validationResult(req);
  if (!valires.isEmpty()) {
    const err = new Error(valires.array()[0].msg);
    throw err;
  }
  logger.info(`Hello ${req.query.person}!`);
  res.send(`Hello ${req.query.person}!`);
});

validationResult()用法获取校验结果,valires是校验结果,主要结构如下:

ts 复制代码
{
  //...
	errors: []
}

errors需要通过valires.array()来得到,当然序列反序列化也行

每一项error结构如下:

ts 复制代码
{
	"type": string,
	"msg": string,
	"path": string, //如上面检查的person
	"location": string //如query,body..
}

如果需要检验多个参数,就放进数组即可:

js 复制代码
[
  validator.query('person').trim().notEmpty().escape().withMessage("person不能为空"),
  validator.query('address').trim().notEmpty().escape().withMessage("address不能为空")
]

封装剥离

之前的写法,是把错误处理和定义都直接写在路由上,臃肿且代码侵入性较强,我们可以进一步封装:

Checker:

这个示例采取了检验并发竞赛的机制,你也可以使用其它的并发或者同步机制:

js 复制代码
/**
 * Validator Race checker
 * @param {validator.ValidationChain[]} validChain 
 * @returns 
 */
const ValidRace = (validChain)=>{
  return async (req, res, next) => {
    await Promise.race(validChain.map(validate => validate.run(req)))
    const valires = validator.validationResult(req);
    if (!valires.isEmpty()) {
      console.log(valires.array());
      const err = new Error(valires.array()[0].msg);
      throw err;
    }
    next();
  }
}

然后在路由上使用即可:

js 复制代码
router.get('/greet2',
  ValidRace([
    validator.query('age').trim()
      .notEmpty().withMessage("age不能为空").bail()
      .isInt().withMessage("age必须是正整数").bail().toInt()
  ]),
(req, res, next) => {
  logger.info(`Hello ${req.query.person}!`);
  res.send(`Hello ${req.query.person}!`);
});

bail()的用处是,如果前面出错就终止检验链,不加的话,age空了还会往后面检验是不是整数。

当然你也可以赋给一个变量,然后再引进来:

js 复制代码
const CheckGreet2 = ValidRace([
  validator.query('age').trim()
    .notEmpty().withMessage("age不能为空").bail()
    .isInt().withMessage("age必须是正整数").bail().toInt()
]);
router.get('/greet2', CheckGreet2, (req, res, next) => {
  logger.info(`Hello ${req.query.person}!`);
  res.send(`Hello ${req.query.person}!`);
});

express-validator的用法远远不止于此,详见官方文档https://express-validator.github.io/docs


下一节-使用zod检验

相关推荐
kylinxjd9 分钟前
spring boot发送邮件
java·spring boot·后端·发送email邮件
汪子熙18 分钟前
Angular 服务器端应用 ng-state tag 的作用介绍
前端·javascript·angular.js
2401_857439693 小时前
Spring Boot新闻推荐系统:用户体验优化
spring boot·后端·ux
进击的女IT4 小时前
SpringBoot上传图片实现本地存储以及实现直接上传阿里云OSS
java·spring boot·后端
一 乐5 小时前
学籍管理平台|在线学籍管理平台系统|基于Springboot+VUE的在线学籍管理平台系统设计与实现(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·学习
昨天;明天。今天。6 小时前
案例-表白墙简单实现
前端·javascript·css
安冬的码畜日常6 小时前
【玩转 JS 函数式编程_006】2.2 小试牛刀:用函数式编程(FP)实现事件只触发一次
开发语言·前端·javascript·函数式编程·tdd·fp·jasmine
小御姐@stella6 小时前
Vue 之组件插槽Slot用法(组件间通信一种方式)
前端·javascript·vue.js
GISer_Jing6 小时前
【React】增量传输与渲染
前端·javascript·面试
GISer_Jing6 小时前
WebGL在低配置电脑的应用
javascript