了解如何验证在你的Express端点中作为输入的任何数据
假设你有一个POST端点,接受姓名、电子邮件和年龄参数。
const express = require('express')
const app = express()
app.use(express.json())
app.post('/form', (req, res) => {
const name = req.body.name
const email = req.body.email
const age = req.body.age
})
你如何对这些结果进行服务器端验证,以确保。
- name是一个至少有3个字符的字符串?
- 电子邮件是一个真实的电子邮件?
- 年龄是一个数字,在0到110之间?
在Express中处理来自外部的任何输入的验证的最好方法是使用express-validator 包。
npm install express-validator
你需要软件包中的check 和validationResult 对象。
const { check, validationResult } = require('express-validator');
我们传递一个check() 调用的数组作为post() 调用的第二个参数。每个check() 调用都接受参数名称作为参数。然后我们调用validationResult() ,以验证是否有验证错误。如果有的话,我们把它们告诉客户。
app.post('/form', [
check('name').isLength({ min: 3 }),
check('email').isEmail(),
check('age').isNumeric()
], (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() })
}
const name = req.body.name
const email = req.body.email
const age = req.body.age
})
注意我用了
isLength()isEmail()isNumeric()
还有很多这样的方法,都来自validator.js,包括。
contains(), 检查值是否包含指定的值equals(), 检查值是否等于指定的值isAlpha()isAlphanumeric()isAscii()isBase64()isBoolean()isCurrency()isDecimal()isEmpty()isFQDN(), 是一个完全合格的域名?isFloat()isHash()isHexColor()isIP()isIn(), 检查值是否在一个允许值的数组中isInt()isJSON()isLatLong()isLength()isLowercase()isMobilePhone()isNumeric()isPostalCode()isURL()isUppercase()isWhitelisted(), 根据允许的字符白名单检查输入的内容
你可以使用matches() ,根据正则表达式验证输入。
可以用以下方法检查日期
isAfter(), 检查输入的日期是否在你通过的日期之后isBefore(), 检查输入的日期是否在你通过的日期之前。isISO8601()isRFC3339()
关于如何使用这些验证器的确切细节,请参考github.com/chriso/vali…
所有这些检查都可以通过管道连接来组合。
check('name')
.isAlpha()
.isLength({ min: 10 })
如果有任何错误,服务器会自动发送一个响应来传达错误。例如,如果电子邮件是无效的,这就是将被返回的内容。
{
"errors": [{
"location": "body",
"msg": "Invalid value",
"param": "email"
}]
}
这个默认的错误可以通过使用withMessage() ,为你执行的每一个检查重写。
check('name')
.isAlpha()
.withMessage('Must be only alphabetical chars')
.isLength({ min: 10 })
.withMessage('Must be at least 10 chars long')
如果你想写你自己的特殊的、自定义的验证器呢?你可以使用custom 验证器。
在回调函数中,你可以通过抛出一个异常,或者返回一个拒绝的承诺来拒绝验证。
app.post('/form', [
check('name').isLength({ min: 3 }),
check('email').custom(email => {
if (alreadyHaveEmail(email)) {
throw new Error('Email already registered')
}
}),
check('age').isNumeric()
], (req, res) => {
const name = req.body.name
const email = req.body.email
const age = req.body.age
})
自定义验证器。
check('email').custom(email => {
if (alreadyHaveEmail(email)) {
throw new Error('Email already registered')
}
})
可以改写为
check('email').custom(email => {
if (alreadyHaveEmail(email)) {
return Promise.reject('Email already registered')
}
})