数据验证的位置:
- 前端(客户端)为了用户体验
- 路由层:验证接口格式是否正常
- 业务逻辑层:保证业务完整性
- 数据库验证:保证数据完整性
相关库:
- validator:用于验证某个字符串是否满足某个规则
- validator.js:用于验证某个对象的树形是否满足某些规则
常用验证函数
-
验证电子邮件地址
jsconst email = '[email protected]'; console.log(validator.isEmail(email)); // true
-
验证URL
jsconst url = 'https://example.com'; console.log(validator.isURL(url)); // true
-
验证IP地址
jsconst ip = '192.168.1.1'; console.log(validator.isIP(ip)); // true
-
验证手机号码
jsconst phone = '13800138000'; console.log(validator.isMobilePhone(phone, 'zh-CN')); // true
-
验证字符串是否为数字
jsconst num = '123'; console.log(validator.isNumeric(num)); // true
-
验证字符串是否为日期
jsconst date = '2023-10-01'; console.log(validator.isDate(date)); // true
-
验证字符串是否为JSON
jsconst json = '{"name": "John"}'; console.log(validator.isJSON(json)); // true
常用净化函数
-
去除字符串两端的空白字符
jsconst str = ' hello '; console.log(validator.trim(str)); // 'hello'
-
转义HTML
jsconst html = '<script>alert("xss")</script>'; console.log(validator.escape(html)); // '<script>alert("xss")</script>'
-
去除非法字符
jsconst str = 'Hello <world>!'; console.log(validator.stripLow(str)); // 'Hello !'
自定义验证
validator.js
还允许你自定义验证规则。例如,你可以使用 matches
函数来验证字符串是否符合特定的正则表达式:
js
const str = 'abc123';
console.log(validator.matches(str, /^[a-z0-9]+$/)); // true
链式调用
validator.js
支持链式调用,可以一次性进行多个验证:
js
const email = '[email protected]';
const result = validator.isEmail(email) && validator.isLength(email, { min: 5, max: 30 });
console.log(result); // true
完整示例
必须验证的属性加上:presence:true
不允许以下格式存在(验证不通过):allowEmpty:false
- {}
- ""
- " "
js
exports.addStudent =async function (stuObj){
//挑选属性
stuObj=pink(stuObj,"name","birthday","sec","mobile","ClassId");
//自定义规则
validata.validators.classExits = async function(value){
const c =await Class.findByPk(value)
if(c){
return;
}
return "班级不存在";
}
const rule ={
//验证规则
name:{
presence:{
allowEmpty:false
},
type:"string",
length:{
minimum:2,
maximum:10
}
},
birthday:{
presence:{
allowEmpty:false
},
datetime:{
dateOnly:true,
earliest:moment.utc().subtract(100,"y"),
latest:+momnet.utc().subtract(5,"y")
},
},
sec:{
presence:{
allowEmpty:false
},
},
mobile:{
presence:{
allowEmpty:false
},
format:{
pattern:/^1\d{10}/
}
},
ClassId:{
presence:true,
// //严格
// type:"integer",
//不严格
numericality:{
onlyInteger:true,
strict:false,
},
classExits:true
}
};
await validate.async(stuObj,rule);
const ins = await Student.create(stuObj);
return ins.toJSON();
}
js
const validate = require("validate.js");
const moment = require("moment");
validate.extend(validate.validators.datetime, {
/**
* 该函数会自动用于日期格式转换
* 它会在验证时自动触发,它需要将任何数据转换为时间戳返回
* 如果无法转换,返回NaN
* @param {*} value 传入要转换的值
* @param {*} options 针对某个属性的验证配置
*/
parse(value, options) {
let formats = ["YYYY-MM-DD HH:mm:ss", "YYYY-M-D H:m:s", "x"];
if (options.dateOnly) {
formats = ["YYYY-MM-DD", "YYYY-M-D", "x"];
}
return +moment.utc(value, formats, true);
},
/**
* 用户显示错误消息时,使用的显示字符串
*/
format(value, options) {
let format = "YYYY-MM-DD";
if (!options.dateOnly) {
format += " HH:mm:ss";
}
return moment.utc(value).format(format);
},
}
对象属性处理:
js
exports.pick = function (obj, ...props) {
if (!obj || typeof obj !== "object") {
return obj;
}
const newObj = {};
for (const key in obj) {
if (props.includes(key)) {
newObj[key] = obj[key];
}
}
return newObj;
};