我现在已经使用了Joi验证一段时间了,对于大多数情况来说它非常可靠,但每次我需要做一些自定义的事情它需要更多的工作。作为一个学习实验,我一直在考虑编写自己的轻量级JSON验证“样板”。
前提:
让我们考虑来自POST的这小块JSON:
{
"name": "Anders",
"dur": 3600000,
"staff": [
"Eric",
"John",
],
"unwantedProp": "foo"
}
我想
name
,dur
和staff
。忽略所有其他。 name
为字符串。dur
是数字。 (或转换为字符串)。staff
是数组,并且只包含字符串。 首先,我编写了这段代码并将其放入模块中。
var error = function (message, status) {
var e = new Error(message);
e.status = status;
return e;
};
module.exports.validateClient = function(json, callback) {
var result = {};
if (!json.hasOwnProperty('name')) {
return callback(error('name is not defined', 400));
} else if (typeof json.name === 'string') {
result.name = json.name
} else {
return callback(error('name must be a string', 400));
}
if (!json.hasOwnProperty('dur')) {
return callback(error('dur is not defined', 400));
} else if (typeof json.dur === 'number') {
result.dur = Math.floor( json.dur )
} else if (typeof json.dur === 'string') {
result.dur = parseInt(json.dur, 10);
} else {
return callback(error('dur must be a number', 400));
}
if (!json.hasOwnProperty('staff')) {
return callback(error('staff is not defined', 400));
} else if (Array.isArray(json.staff)) {
var valid = true
json.staff.forEach(function (elem) {
if (typeof elem !== 'string') {
valid = false;
}
})
if (valid) {
result.staff = json.staff;
} else {
return callback(error('staff may only contain strings', 400));
}
} else {
return callback(error('staff must be an array', 400));
}
callback(null, result);
};
然后我使用这个函数:
hlpr.validateClient(req.body, function(err, result) {
if (err) return next(err);
res.json(result);
})
尽管这有效,但我知道if语句完全混乱......而且它完全不可重复使用。 这让我有点模糊的问题。有人可以给我一些指导如何将这个混乱分解为可以应用于其他JSON数据的较小的可重用函数...也许帮助我一个模块化的if语句混乱部分的例子。
答案 0 :(得分:1)
你应该使用某种模式来验证你的东西。
一种非常灵活的方法是允许某些属性的自定义验证功能。
以下是一个例子:
var source ={
"name": "Anders",
"dur": 3600000,
"staff": [
"Eric",
"John",
],
"unwantedProp": "foo"
}
var schema = {
"name": function(name){return typeof name ==="string"&&name.length<10},
"dur": "number",
"staff": ["string"],
}
function validate(source, schema, result){
result = result||{}
var error
Object.keys(schema).forEach(function(key){
var val = source[key]
var type = schema[key]
if(type === "string"){
if(typeof val ==="string"){
result[key] = val
}else{
error = {success:false, message:val+" is not a string."}
}
}else if(type === "number"){
if(typeof val ==="number"){
result[key] = val
}else if (!isNaN(parseInt(val))){
result[key] = parseInt(val)
}else{
error = {success:false, message:val+" is not a number."}
}
}else if (type.constructor === Array){
if(val.constructor === Array){
var arr_type = type[0]
var valid = true
val.forEach(function(mem){
if(typeof mem !==arr_type){valid = false}
})
if(valid){
result[key] = val
}else{
error = {success:false, message:val+" is not a "+ arr_type+" array."}
}
}else{
error = {success:false, message:val+" is not an array."}
}
}else if (typeof type === "function"){
if(type(val)){
result[key] = val
}else{
error = {success:false, message:"Custom validation "+type+ " returned false for "+val+"."}
}
}
})
return error||{sucess:true, result:result}
}
答案 1 :(得分:1)
如果任何api有错误的json身体通过。 在全局验证应用程序服务器的任何api json body。
例如 - &gt; 登录api要求正文低于格式,但是错误的身体有“,”左。
"email":"alarm@gmail.com", // suppose, body have , is not added, then throw error message:- wrong body of json
以下代码在node.js中非常有用
var express=require('express');
var bodyParser=require('body-parser');
var app=express();
app.use(bodyParser.json());
app.use(function(err,req,res,callback){
if(err instanceof SyntaxError && err.status===400 && 'body' in err){
res.status(403).send({
"error":false,
"message":"Wrong Body of json",
"response":null
})
res.end()
}
});
app.use(bodyParser());
希望它对你有所帮助。另请查看完整文章:
https://plus.google.com/u/0/+Oodlestechnologies/posts/M8WLCYXc4Bc