当前位置: 首页 > news >正文

Node.js 》》数据验证 Joi 、express-joi

express-joi、joi

 joi是nodej的一个工具模块,主要用于JavaScript对象的校验。它是一种简单易用的javacript对象约束描述语言,可以轻松解决nodejs开发中的各种参数的校验。1. string()    			    值必须是字符串2. alphanum()   				值只能包含a-zA-Z的字符串3. min(n)       				最小长度4. max(n)       				最大长度5. required    			    值必填项,   不能为  undefined6. pattern(正则表达式)           值必须符号正则表达式
express-joi 是一个基于 Joi 的中间件,用于在 Express 应用中进行参数验证。它可以帮助我们验证请求中的 body、query 和 params 数据,确保数据的有效性和安全性。
#  安装npm install @escook/express-joinpm install joi
#  导入const express = require('express');const app = express();const Joi = require('joi');const expressJoi = require('@escook/express-joi');	
# 定义验证规则const userSchema = {body: {username: Joi.string().alphanum().min(3).max(12).required(),password: Joi.string().pattern(/^[\S]{6,15}$/).required(),repassword: Joi.ref('password')},query: {name: Joi.string().alphanum().min(3).required(),age: Joi.number().integer().min(1).max(100).required()},params: {id: Joi.number().integer().min(0).required()}}
# 使用中间件进行验证  // 数据验证通过之后,会把这次请求流转给后面的路由处理函数// 数据验证失败 ,  终止后续代码执行,并抛出一个 全局Error 错误,进入全局错误中间件中app.post('/adduser/:id', expressJoi(userSchema), function(req, res) {const body = req.body;res.send(body);})
# 错误处理app.use(function(err, req, res, next) {if (err instanceof Joi.ValidationError) {return res.send({ status: 1, message: err.message });}res.send({ status: 1, message: err.message });})
# 启动服务app.listen(3001, function() {console.log('Express server running at http://127.0.0.1:3001');})

案例

》》》创建验证规则文件 (schema/user.js)

// schema/user.js
const joi = require('joi')// 用户注册和登录表单的验证规则
const username = joi.string().alphanum().min(3).max(12).required()
const password = joi.string().pattern(/^[\S]{6,15}$/).required()
const email = joi.string().email().required()// 注册和登录表单的验证规则对象
exports.reg_login_schema = {// 表示对 req.body 中的数据进行验证body: {username,password,email}
}// 更新用户信息验证规则
exports.update_userinfo_schema = {body: {id: joi.number().integer().min(1).required(),nickname: joi.string().required(),email: joi.string().email().required()}
}// 更新密码验证规则
exports.update_password_schema = {body: {oldPwd: password,newPwd: joi.not(joi.ref('oldPwd')).concat(password)}
}// 更新头像验证规则
exports.update_avatar_schema = {body: {avatar: joi.string().dataUri().required()}
}

》》创建路由文件 (routes/user.js)

// routes/user.js
const express = require('express')
const router = express.Router()
const expressJoi = require('@escook/express-joi')
//  路由处理模块
const userHandler = require('../handler/user')
const { reg_login_schema,update_userinfo_schema,update_password_schema,update_avatar_schema
} = require('../schema/user')// 注册新用户
router.post('/register', expressJoi(reg_login_schema), userHandler.register)// 登录
router.post('/login', expressJoi(reg_login_schema), userHandler.login)// 更新用户基本信息
router.post('/userinfo', expressJoi(update_userinfo_schema), userHandler.updateUserInfo)// 重置密码
router.post('/updatepwd', expressJoi(update_password_schema), userHandler.updatePassword)// 更新头像
router.post('/update/avatar', expressJoi(update_avatar_schema), userHandler.updateAvatar)module.exports = router

》》创建控制器文件 (handler/user.js)

// handler/user.js
exports.register = (req, res) => {// 这里的 req.body 数据已经通过验证res.send({status: 0,message: '注册成功!',data: req.body})
}exports.login = (req, res) => {res.send({status: 0,message: '登录成功!',data: req.body})
}exports.updateUserInfo = (req, res) => {res.send({status: 0,message: '更新用户信息成功!',data: req.body})
}exports.updatePassword = (req, res) => {res.send({status: 0,message: '更新密码成功!',data: req.body})
}exports.updateAvatar = (req, res) => {res.send({status: 0,message: '更新头像成功!',data: req.body})
}

》》创建主应用文件 (app.js)

// app.js
const express = require('express')
const app = express()// 配置解析表单数据的中间件
app.use(express.urlencoded({ extended: false }))
app.use(express.json())// 导入并注册用户路由模块
const userRouter = require('./routes/user')
app.use('/api', userRouter)// 错误中间件
app.use((err, req, res, next) => {// 数据验证失败if (err instanceof joi.ValidationError) {return res.send({status: 1,message: err.message})}// 未知错误res.send({status: 1,message: err.message})
})// 启动服务器
app.listen(3000, () => {console.log('server running at http://127.0.0.1:3000')
})

高级验证案例

》》自定义验证消息

// schema/user.js
exports.reg_login_schema = {body: {username: joi.string().alphanum().min(3).max(12).required().messages({'string.base': '用户名必须是字符串','string.alphanum': '用户名只能包含字母和数字','string.min': '用户名长度不能小于3','string.max': '用户名长度不能大于12','any.required': '用户名是必填项'}),password: joi.string().pattern(/^[\S]{6,15}$/).required().messages({'string.base': '密码必须是字符串','string.pattern.base': '密码长度6-15位,不能包含空格','any.required': '密码是必填项'})}
}

》》条件验证

// schema/user.js
exports.update_userinfo_schema = {body: {id: joi.number().integer().min(1).required(),nickname: joi.string().required(),email: joi.string().email().required(),// 只有 is_vip 为 true 时才需要验证 vip_expire 字段is_vip: joi.boolean(),vip_expire: joi.when('is_vip', {is: true,then: joi.date().required(),otherwise: joi.optional()})}
}

》》数组验证

// schema/product.js
const joi = require('joi')exports.add_product_schema = {body: {name: joi.string().required(),price: joi.number().min(0).required(),// 验证数组tags: joi.array().items(joi.string().valid('新品', '热销', '折扣')).min(1).required(),// 验证对象数组specs: joi.array().items(joi.object({name: joi.string().required(),value: joi.string().required()})).min(1).required()}
}
http://www.lryc.cn/news/614448.html

相关文章:

  • HarmonyOS SDK助力讯飞听见App能力建设
  • node.js 学习笔记2 进程/线程、fs
  • 力扣-56.合并区间
  • 经常问的14000
  • 智能巡检机器人的进化:当传统巡检遇上Deepoc具身智能外拓开发板
  • Visual Studio 2019 + Qt + MySQL 开发调试全过程问题详解
  • Vue 3 表单数据缓存架构设计:从问题到解决方案
  • 前端基础之《Vue(29)—Vue3 路由V4》
  • ADB打印设备日志相关
  • 手机拍照识别中模糊场景准确率↑37%:陌讯动态适配算法实战解析
  • 用LaTeX优化FPGA开发:结合符号计算与Vivado工具链(二)
  • 大模型量化上溢及下溢解析
  • ESP32-menuconfig(4) -- Partition Table
  • Web Worker 性能革命:让浏览器多线程为您的应用加速
  • ChipCamp探索系列 -- 1. Soft-Core RISC-V on FPGA
  • 【10】C#实战篇——C# 调用 C++ dll(C++ 导出函数、C++导出类)
  • 华清远见25072班C语言学习day5
  • Advances and Challenges in Foundation Agents--Memory调研
  • WPF 双击行为实现详解:DoubleClickBehavior 源码分析与实战指南
  • 基于ffmpeg和rk3588的mpp编解码库多路融屏程序设计
  • 贝叶斯定理 vs 条件概率
  • Redis(⑤-线程池隔离)
  • 【从0到1制作一块STM32开发板】6. PCB布线--信号部分
  • React函数组件灵魂搭档:useEffect深度通关指南!
  • 如何实现在多跳UDP传输场景,保证单文件和多文件完整传输的成功率?
  • 三相交流电机旋转磁场产生原理
  • Django模型开发全解析:字段、元数据与继承的实战指南
  • Flutter开发 多孩子布局组件
  • [202403-B]算日期
  • 蓝桥杯----大模板