JavaScript (Node.js) 中的数据验证:Joi 和 Yup
在任何 Web 应用程序中,尤其是基于 Node.js 的应用程序,关键任务之一就是检查传入数据。没有验证,您将面临数据库错误、安全漏洞(SQL 注入、XSS)或服务器行为异常的风险。在本文中,我们将介绍两个最流行的验证库:Joi 和 Yup。您将学习如何安装它们、创建模式以及如何与 Express 集成。
为什么需要服务器端验证?
客户端验证(HTML5 或浏览器中的 JavaScript)很方便,但很容易被绕过。因此,服务器端检查是强制性的。它确保:
- 数据类型符合预期(字符串、数字、数组)。
- 必填字段不为空。
- 数据不超过允许的大小。
- 格式(电子邮件、URL、电话号码)正确。
Joi 库
Joi 是来自 Hapi.js 创建者的强大验证器。它支持复杂模式、自定义错误消息和异步检查。
安装
npm install joi用户注册模式示例
const Joi = require('joi');
const userSchema = Joi.object({ username: Joi.string() .alphanum() .min(3) .max(30) .required() .messages({ 'string.min': '用户名至少需要3个字符', 'string.max': '用户名不能超过30个字符' }), email: Joi.string() .email({ tlds: { allow: false } }) .required(), password: Joi.string() .pattern(new RegExp('^[a-zA-Z0-9]{8,30}$')) .required(), birth_year: Joi.number() .integer() .min(1900) .max(2024)});
// 验证app.post('/register', (req, res) => { const { error, value } = userSchema.validate(req.body, { abortEarly: false }); if (error) { return res.status(400).json({ status: 'error', message: error.details.map(d => d.message).join(', ') }); } res.json({ status: 'success', data: value });});Joi 的高级功能
- 数组验证:
Joi.array().items(Joi.string()) - 条件规则:
.when('role', { is: 'admin', then: Joi.required() }) - 自定义函数:
.custom((value, helpers) => { ... })
Yup 库
Yup 是一个轻量级且直观的库,在 React 生态系统(Formik)中很受欢迎。但它同样适用于服务器端。
安装
npm install yup登录模式示例
const yup = require('yup');
const loginSchema = yup.object().shape({ email: yup.string() .email('请输入有效的电子邮件') .required('电子邮件是必填项'), password: yup.string() .min(8, '密码长度至少为8个字符') .max(50) .required('密码是必填项')});
// Express 中间件async function validateLogin(req, res, next) { try { const validatedData = await loginSchema.validate(req.body, { abortEarly: false }); req.validatedData = validatedData; next(); } catch (err) { res.status(400).json({ status: 'error', errors: err.errors // 错误消息数组 }); }}
app.post('/login', validateLogin, (req, res) => { res.json({ status: 'success', data: req.validatedData });});Yup 的特点
- 默认异步验证(返回 Promise)。
- 数据转换:
.transform((value) => value.tr