了解如何验证在你的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')
}
})