開發(fā)web應用時,我們總是需要對用戶的數據進行驗證,這包括客戶端的驗證以及服務端的驗證党远,僅僅依靠客戶端的驗證是不可靠的,畢竟我們不能把所有的用戶都當成是普通用戶富弦,繞過客戶端的驗證對于部分用戶來說并不是什么難事沟娱,因此所有數據應該在服務端也進行一次驗證。Express應用可以通過express-validator進行數據驗證腕柜,這樣就不必自己煩瑣的為每一個數據單獨寫驗證程序(過來人告訴你這感覺簡直糟透了)济似。
通過一個簡單的例子讓我們來看看express-validator的便捷矫废,讓用戶上傳一些數據,表單如下:
最簡單的服務端代碼如下:
var express = require('express');
var bodyParser = require('body-parser');
var expressValidator = require('express-validator');
var check = require('express-validator/check').check;
var validationResult = require('express-validator/check').validationResult;
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:false}));
app.get('/', function(req, res) {
res.sendFile('index.html', {root:'./test'});
});
app.post('/data', [
check('email')
.isEmail()
.withMessage('must be an email'),
check('username')
.isLength({min:6})
.withMessage('ust be at least 6 chars long')
],function(req, res) {
var errors = validationResult(req);
if(!errors.isEmpty()) {
return res.json({errors: errors.mapped()});
}
res.json({msg:'success'});
});
app.listen(4000);
當用戶上傳數據之后會在服務端對用戶的用戶名和郵箱進行驗證砰蠢,當數據不符合時蓖扑,錯誤信息顯示如下:
從上面的例子中可以看到對數據的驗證錯誤可以隨時獲取,從而進行處理台舱。
validationResult方法獲取捕獲的錯誤律杠,mapped()方法獲取具體的錯誤信息。
express-validator是基于validator.js的竞惋,express-validator也類似將API分為check和filter兩個部分(關于validator.js的使用可以參考使用validator.js對字符串數據進行驗證
)
check部分
check(field[, message])
field是一個字符串或者是一個數組柜去,message是驗證不通過的錯誤信息,返回驗證鏈(鏈式調用)
check方法默認會驗證req.body拆宛、req.cookies嗓奢、req.headers、req.params浑厚、req.query中的字段股耽,如果有相同字段,其中一個不通過就會顯示錯誤信息瞻颂。
如將以上例子的post地址新增一個名為email的query則錯誤信息如下:
注意location的值豺谈。
如果需要單獨驗證req.body、req.cookies贡这、req.headers茬末、req.params、req.query的其中一個目標的字段盖矫,則可以使用對應的方法body丽惭、cookie、header辈双、param责掏、query、body湃望、
oneOf(validationChains[, message])
validationChains是驗證鏈組成的數組换衬,如果驗證鏈至少有一條通過則不顯示錯誤。
var express = require('express');
var bodyParser = require('body-parser');
var expressValidator = require('express-validator');
var check = require('express-validator/check').check;
var oneOf = require('express-validator/check').oneOf;
var validationResult = require('express-validator/check').validationResult;
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:false}));
app.get('/', function(req, res) {
res.sendFile('index.html', {root:'./test'});
});
app.post('/data', oneOf([
check('email')
.isEmail()
.withMessage('must be an email'),
check('username')
.isLength({min:6})
.withMessage('ust be at least 6 chars long')
]),function(req, res) {
var errors = validationResult(req);
if(!errors.isEmpty()) {
return res.json({errors: errors.mapped()});
}
res.json({msg:'success'});
});
app.listen(4000);
validationResult(req)
獲取驗證的結果是否通過
buildCheckFunction(locations)
從指定的locaation中構建check证芭,locations是body瞳浦、cookies、headers废士、params叫潦、query一個或者幾個組成的數組,相當于指定位置的字段進行驗證(請不要忘記check方法會對這5個部分都進行驗證)
var buildCheckFunction = require('express-validator/check').buildCheckFunction;
var checkBodyAndQuery = buildCheckFunction(['body','query']);
filter部分
matchedData(req[, options])
獲取check的字段數據官硝,也就是獲取上文例子出現的錯誤信息中的value字段值矗蕊,options為一個json對象短蜕,允許的字段為
{
onlyValidData:true,
locations:[]
}
onlyValidData顯然就是是否僅僅獲取驗證的字段值,默認為true傻咖,locations就是指定位置朋魔。
app.post('/data', [
check('email')
.isEmail()
.withMessage('must be an email'),
check('username')
.isLength({min:6})
.withMessage('ust be at least 6 chars long')
],function(req, res) {
var queryData = matchedData(req, {locations: ['query']});
var bodyData = matchedData(req, {locations: ['body']});
console.log(queryData);
console.log(bodyData);
var errors = validationResult(req);
if(!errors.isEmpty()) {
return res.json({errors: errors.mapped()});
}
res.json({msg:'success'});
});
sanitize(fields)
類似于check,只不過是返回一個處理鏈没龙,理所當然有類似的sanitizeBody铺厨、sanitizeCookie缎玫、sanitizeParam硬纤、sanitizeQuery、buildSanitizeFunction赃磨。(注意req.headers在這里不適用)
customSanitizer(sanitizer)
進行自定義處理程序
除此之外筝家,express-validator保留了版本3的作為express中間件的使用方式。
var express = require('express');
var expressValidator = require('express-validator');
app.use(expressValidator({
errorFormatter: function(param, message, value) {
return {
param: param,
message: message,
value: value
}
},
customValidators: {
isEmail: function(value) {
return /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value);
},
isString: function(value) {
return typeof value === 'string';
},
isObject: function(value) {
return (typeof value === 'object' && !Array.isArray(value));
},
isArray: function(value){
return Array.isArray(value);
},
isBoolean: function(value) {
return value === true || value === false;
},
custom: function(value, callback) {
if(typeof value !== 'undefined') {
callback(value);
return true;
} else {
return false;
}
}
}
}));
可以在使用use加載中間件的時候自定義第三方驗證方法和處理方法邻辉。
驗證數據時的使用方式如下:
req.checkBody('email', '郵件格式不正確').isEmail();
req.checkBody('password', '密碼不能小于6位').isLength(6);