栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > Web开发 > JavaScript

#试用# #nodejs# Joi库进行入参校验

JavaScript 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

#试用# #nodejs# Joi库进行入参校验

Joi是什么?

官方文档描述是:joi lets you describe your data using a simple, intuitive, and readable language.
简单理解就是:可以简单直接描述你的数据模型的语言。
所以重点是描述,然后校验很简单。
官方文档地址:joi.dev/api/?v=17.4.0

安装

在项目目录里执行 npm i joi

试用环境

@google-cloud/functions-framework

简单试用

对一个字符串型参数进行校验
代码如下:

const Joi = require('joi');
const schema = Joi.object({
username: Joi.string()
  .alphanum()
  .min(3)
  .max(30)
})

exports.helloWorld = (req, res) => {
  const { error, value } = schema.validate(req.query)
  if (error) {
    return res.status(422).json({ error: error })
  }
  res.send('Hello, World') 
}

效果如下:
访问 http://localhost:8080/
返回 Hello, World
访问 http://localhost:8080/?username=aaaa
返回 Hello, World
访问 http://localhost:8080/?username=aa
返回

{
    "error": {
 "_original": {
     "username": "aa"
 },
 "details": [
     {
  "message": ""username" length must be at least 3 characters long",
  "path": [
      "username"
  ],
  "type": "string.min",
  "context": {
      "limit": 3,
      "value": "aa",
      "label": "username",
      "key": "username"
  }
     }
 ]
    }
}

访问 http://localhost:8080/?username=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
返回

{
    "error": {
 "_original": {
     "username": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
 },
 "details": [
     {
  "message": ""username" length must be less than or equal to 30 characters long",
  "path": [
      "username"
  ],
  "type": "string.max",
  "context": {
      "limit": 30,
      "value": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
      "label": "username",
      "key": "username"
  }
     }
 ]
    }
}

访问 http://localhost:8080/?username=aaaa&password=1234
返回

{
    "error": {
 "_original": {
     "username": "aaaa",
     "password": "1234"
 },
 "details": [
     {
  "message": ""password" is not allowed",
  "path": [
      "password"
  ],
  "type": "object.unknown",
  "context": {
      "child": "password",
      "label": "password",
      "value": "1234",
      "key": "password"
  }
     }
 ]
    }
}
对body进行校验

增加必填校验
代码:

const Joi = require('joi');
const schema = Joi.object({
    username: Joi.string()
 .alphanum()
 .min(3)
 .max(30),
    password: Joi.string()
 .alphanum()
 .min(6)
 .max(12)
})

exports.helloWorld = (req, res) => {
    const { error, value } = schema.validate(req.body)
    if (error) {
 return res.status(422).json({ error: error })
    }
    console.info(value)
    res.send(value)
};

用postman访问http://localhost:8080
输入数据:

{
    "username": "postman",
    "password": "123456"
}

返回:

{
    "username": "postman",
    "password": "123456"
}

输入数据:

{
    "username": "postman",
    "password": "123456",
		"age":30
}

返回:

{
    "error": {
 "_original": {
     "username": "postman",
     "password": "123456",
     "age": "30"
 },
 "details": [
     {
  "message": ""age" is not allowed",
  "path": [
      "age"
  ],
  "type": "object.unknown",
  "context": {
      "child": "age",
      "label": "age",
      "value": "30",
      "key": "age"
  }
     }
 ]
    }
}

输入数据:

{
    "username": "postman",
    "password": ""
}

返回:

{
    "error": {
 "_original": {
     "username": "postman",
     "password": ""
 },
 "details": [
     {
  "message": ""password" is not allowed to be empty",
  "path": [
      "password"
  ],
  "type": "string.empty",
  "context": {
      "label": "password",
      "value": "",
      "key": "password"
  }
     }
 ]
    }
}
校验两个参数是否都输入

和required是有差别的
代码:

const Joi = require('joi');
const schema = Joi.object({
    username: Joi.string()
 .alphanum()
 .min(3)
 .max(30),
    password: Joi.string()
 .alphanum()
 .min(6)
 .max(12),
    mobile: Joi.string()
 .alphanum()
}).and('username', 'password')

exports.helloWorld = (req, res) => {
    const { error, value } = schema.validate(req.query)
    if (error) {
 return res.status(422).json({ error: error })
    }
    console.info(value)
    res.send(value)
};

输入数据:

http://localhost:8080/?username=aaaaaaa&password=123456

返回:

{
    "username": "aaaaaaa",
    "password": "123456"
}

输入数据:

http://localhost:8080/?username=aaaaaaa&mobile=123456

返回:

{
    "error": {
 "_original": {
     "username": "aaaaaaa",
     "mobile": "123456"
 },
 "details": [
     {
  "message": ""value" contains [username] without its required peers [password]",
  "path": [],
  "type": "object.and",
  "context": {
      "present": [
   "username"
      ],
      "presentWithLabels": [
   "username"
      ],
      "missing": [
   "password"
      ],
      "missingWithLabels": [
   "password"
      ],
      "label": "value",
      "value": {
   "username": "aaaaaaa",
   "mobile": "123456"
      }
  }
     }
 ]
    }
}

输入:http://localhost:8080/?mobile=123456
返回:

{
    "mobile": "123456"
}
二选一及伴随

代码

const Joi = require('joi');
const schema = Joi.object({
    username: Joi.string()
 .alphanum()
 .min(3)
 .max(30),
    password: Joi.string()
 .alphanum()
 .min(6)
 .max(12),
    mobile: Joi.string()
 .alphanum()
}).xor('username', 'mobile')
  .with('username', 'password')
  .with('mobile','password')

exports.helloWorld = (req, res) => {
    const { error, value } = schema.validate(req.query)
    if (error) {
 return res.status(422).json({ error: error })
    }
    console.info(value)
    res.send(value)
};

输入:http://localhost:8080/?mobile=123456789&password=654321
输出:

{
    "mobile": "123456789",
    "password": "654321"
}

输入:http://localhost:8080/?mobile=123456
输出:

{
    "error": {
 "_original": {
     "mobile": "123456"
 },
 "details": [
     {
  "message": ""mobile" missing required peer "password"",
  "path": [],
  "type": "object.with",
  "context": {
      "main": "mobile",
      "mainWithLabel": "mobile",
      "peer": "password",
      "peerWithLabel": "password",
      "label": "value",
      "value": {
   "mobile": "123456"
      }
  }
     }
 ]
    }
}

输入:http://localhost:8080/?username=abcdfe&password=654321
输出:

{
    "username": "abcdfe",
    "password": "654321"
}

输入:http://localhost:8080/?username=abcdfe&password=654321&mobile=13999999999
输出:

{
    "error": {
 "_original": {
     "username": "abcdfe",
     "password": "654321",
     "mobile": "13999999999"
 },
 "details": [
     {
  "message": ""value" contains a conflict between exclusive peers [username, mobile]",
  "path": [],
  "type": "object.xor",
  "context": {
      "peers": [
   "username",
   "mobile"
      ],
      "peersWithLabels": [
   "username",
   "mobile"
      ],
      "present": [
   "username",
   "mobile"
      ],
      "presentWithLabels": [
   "username",
   "mobile"
      ],
      "label": "value",
      "value": {
   "username": "abcdfe",
   "password": "654321",
   "mobile": "13999999999"
      }
  }
     }
 ]
    }
}
其他常用功能

直接验证某个变量或者值:Joi.attempt(‘x’, Joi.number());
允许对象里含有未定义的key:Joi.object({ a: Joi.any() }).unknown();
定义参数不能同时出现:

const schema = Joi.object({
    a: Joi.any(),
    b: Joi.any()
}).nand('a', 'b');
转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号