#使用express-validator在Express中驗證輸入
了解如何驗證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個字符的字符串嗎?
- email是一個真實的郵件地址嗎?
- age是一個介於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()
,檢查值是否僅包含ASCII字符isBase64()
,檢查值是否為Base64編碼的字符串isBoolean()
,檢查值是否為布爾值isCurrency()
,檢查值是否是貨幣格式isDecimal()
,檢查值是否為十進制數字isEmpty()
,檢查值是否為空isFQDN()
,檢查值是否為完全限定域名(Fully Qualified Domain Name)isFloat()
,檢查值是否為浮點數isHash()
,檢查值是否是哈希值isHexColor()
,檢查值是否為十六進制顏色isIP()
,檢查值是否為IP地址isIn()
,檢查值是否在一個允許的值的數組中isInt()
,檢查值是否為整數isJSON()
,檢查值是否是有效的JSON字符串isLatLong()
,檢查值是否為緯度和經度值isLength()
,檢查值是否具有指定的長度isLowercase()
,檢查值是否為小寫字母isMobilePhone()
,檢查值是否為有效的手機號碼isNumeric()
,檢查值是否為數字isPostalCode()
,檢查值是否為郵政編碼isURL()
,檢查值是否為URLisUppercase()
,檢查值是否為大寫字母isWhitelisted()
,檢查值是否通過許可字符的白名單
您可以使用matches()
方法對輸入進行正則表達式驗證。
日期可以使用以下方法進行檢查:
isAfter()
,檢查輸入的日期是否在指定日期之後isBefore()
,檢查輸入的日期是否在指定日期之前isISO8601()
,檢查輸入的日期是否為ISO 8601格式isRFC3339()
,檢查輸入的日期是否為RFC3339格式
有關如何使用這些驗證器的詳細信息,請參考 https://github.com/chriso/validator.js#validators。
所有這些檢查都可以通過將它們鏈接在一起進行組合:
check('name')
.isAlpha()
.isLength({ min: 10 })
如果發生任何錯誤,服務器將自動發送響應以通知錯誤。例如,如果郵件地址無效,將返回以下內容:
{
"errors": [{
"location": "body",
"msg": "Invalid value",
"param": "email"
}]
}
對於執行的每個檢查,您可以使用withMessage()
方法覆蓋默認錯誤:
check('name')
.isAlpha()
.withMessage('必須只包含字母字符')
.isLength({ min: 10 })
.withMessage('必須至少10個字符長')
如果您想編寫自己的特殊自定義驗證器該怎麼辦?您可以使用custom
驗證器。
在回調函數中,您可以通過拋出異常或返回一個被拒絕的Promise來拒絕驗證:
app.post('/form', [
check('name').isLength({ min: 3 }),
check('email').custom(email => {
if (alreadyHaveEmail(email)) {
throw new Error('郵件地址已經註冊')
}
}),
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 (已經有這個郵件地址了(email)) {
throw new Error('郵件地址已經註冊')
}
})
也可以重寫為:
check('email').custom(email => {
if (alreadyHaveEmail(email)) {
return Promise.reject('郵件地址已經註冊')
}
})