async-validator
基于 https://github.com/freeformsystems/async-validate 的一个异步表单校验库
API
参考 async-validate 来的
Usage
基本用法包括定义描述符,将其分配给模式,并将要验证的对象和回调函数传递给模式的 validate 方法:
const schema = require('async-validator');
const descriptor = {
name: { type: 'string', required: true },
};
const validator = new schema(descriptor);
validator.validate({ name: 'muji' }, (errors, fields) => {
if (errors) {
// validation failed, errors is an array of all errors
// fields is an object keyed by field name with an array of
// errors per field
return handleErrors(errors, fields);
}
// validation passed
});Validate
/**
* @param {Object} source 要验证的对象(必需)
* @param {Object} options 描述验证处理选项的对象(可选)
* @param {Function} callback 验证完成时调用的回调函数(必需)
*/
function(source, [options], callback)Options
- first
布尔值,当第一个验证规则生成错误时调用回调,不再处理验证规则。如果您的验证涉及多个异步调用(例如,数据库查询),并且您只需要第一个错误,请使用此选项。
- firstFields
Boolean | String [],当指定字段的第一个验证规则生成错误时调用回调,不再处理相同字段的验证规则。true 表示所有字段。
Rules
规则可以是执行验证的函数。
/**
* @param {Object} rule 源描述符中的验证规则,对应于要验证的字段名称。始终为其分配一个字段属性,其中包含要验证的字段的名称
* @param {String} value 要验证的源对象属性的值
* @param {Function} callback 完成验证后调用的回调函数已完成。它期望传递一组Error实例来指示验证失败
* @param {Object} source 传递给validate方法的源对象
* @param {Array} options 其他选项 options.message 包含验证错误消息的对象将与defaultMessages深度合并。
*/
function(rule, value, callback, source, options)传递给 validate 的选项将传递给验证函数,以便您可以在验证函数中引用瞬态数据(例如模型引用)。但是,保留了一些选项名称;如果使用选项对象的这些属性,则会覆盖它们。保留的属性是消息,异常和错误。
const schema = require('async-validator');
const descriptor = {
name(rule, value, callback, source, options) {
const errors = [];
if (!/^[a-z0-9]+$/.test(value)) {
errors.push(
new Error(util.format('%s must be lowercase alphanumeric characters', rule.field)),
);
}
callback(errors);
},
};
const validator = new schema(descriptor);
validator.validate({ name: 'Firstname' }, (errors, fields) => {
if (errors) {
return handleErrors(errors, fields);
}
// validation passed
});针对单个字段测试多个验证规则通常很有用,这样做可以使规则成为对象数组,例如:
const descriptor = {
email: [
{ type: 'string', required: true, pattern: schema.pattern.email },
{
validator(rule, value, callback, source, options) {
var errors = [];
// test if email address already exists in a database
// and add a validation error to the errors array if it does
callback(errors);
},
},
],
};type
指示要使用的验证程序的类型。已识别的类型值为:
- string:必须是 String 类型,这是默认类型
- number:必须是 Number 类型
- boolean:必须是 Boolean 类型
- method:必须是 function 类型
- regexp:必须是 RegExp 的实例或在创建新的 RegExp 时不生成异常的字符串
- integer:必须是 Number 类型且为整数
- float:必须是 Number 类型的浮点数
- array:必须是由 Array.isArray 确定的数组
- object:必须是 object 类型而不是 Array.isArray
- enum:值必须存在于枚举中
- date:值必须有效,由 Date 确定
- url:必须是 url 类型
- hex:必须是十六进制类型
- email:必须是电子邮件类型
Required
必需的 rule 属性指示该字段必须存在于要验证的源对象上。
Pattern
模式规则属性指示值必须匹配以传递验证的正则表达式。
Range
使用 min 和 max 属性定义范围。对于字符串和数组类型,将根据长度进行比较,对于数字类型,数字不得小于 min,也不得大于 max。
Length
要验证字段的确切长度,请指定 len 属性。对于字符串和数组类型,对 length 属性执行比较,对于数字类型,此属性指示数字的完全匹配,即,它可能仅严格等于 len。如果 len 属性与最小和最大范围属性组合,则 len 优先。
Enumerable
要从可能值列表中验证值,请使用带枚举属性的枚举类型,列出该字段的有效值,例如:
const descriptor = {
role: { type: 'enum', enum: ['admin', 'user', 'guest'] },
};Whitespace
通常将仅包含空格的必填字段视为错误。要为仅包含空格的字符串添加其他测试,请将空白属性添加到值为 true 的规则。规则必须是字符串类型。您可能希望清理用户输入而不是测试空白,请参阅 transform 以获取允许您去除空白的示例。
Deep Rules
如果需要验证深层对象属性,则可以通过将嵌套规则分配给规则的 fields 属性来为对象或数组类型的验证规则执行此操作。
const descriptor = {
address: {
type: 'object',
required: true,
fields: {
street: { type: 'string', required: true },
city: { type: 'string', required: true },
zip: { type: 'string', required: true, len: 8, message: 'invalid zip' },
},
},
name: { type: 'string', required: true },
};
const validator = new schema(descriptor);
validator.validate({ address: {} }, (errors, fields) => {
// errors for address.street, address.city, address.zip
});请注意,如果未在父规则上指定必需属性,则对于不在源对象上声明的字段完全有效,并且不会执行深度验证规则,因为没有任何要验证的内容。
深度规则验证为嵌套规则创建模式,因此您还可以指定传递给 schema.validate() 方法的选项。
const descriptor = {
address: {
type: 'object',
required: true,
options: { single: true, first: true },
fields: {
street: { type: 'string', required: true },
city: { type: 'string', required: true },
zip: { type: 'string', required: true, len: 8, message: 'invalid zip' },
},
},
name: { type: 'string', required: true },
};
const validator = new schema(descriptor);
validator.validate({ address: {} }, (errors, fields) => {
// now only errors for street
});父规则也经过验证,因此如果您有一组规则,例如:
const descriptor = {
roles: {
type: 'array',
required: true,
len: 3,
fields: {
0: { type: 'string', required: true },
1: { type: 'string', required: true },
2: { type: 'string', required: true },
},
},
};并提供 { roles:["admin", "user"] } 的源对象,然后将创建两个错误。一个用于数组长度不匹配,另一个用于索引 2 处缺少的所需数组条目。
defaultField
defaultField 属性可与数组或对象类型一起使用,以验证容器的所有值。它可以是包含验证规则的对象或数组。例如:
const descriptor = {
urls: {
type: 'array',
required: true,
defaultField: { type: 'url' },
},
};请注意,defaultField 已扩展为字段,请参阅深层规则。
Transform
有时需要在验证之前转换值,可能是为了强制价值或以某种方式对其进行消毒。为此,请将验证规则添加到转换函数中。该属性在验证之前进行转换,并重新分配给源对象,以便在适当的位置改变属性的值。
var schema = require('async-validator');
var sanitize = require('validator').sanitize;
var descriptor = {
name: {
type: 'string',
required: true,
pattern: /^[a-z]+$/,
transform(value) {
return sanitize(value).trim();
},
},
};
var validator = new schema(descriptor);
var source = { name: ' user ' };
validator.validate(source, (errors, fields) => {
assert.equal(source.name, 'user');
});如果没有转换函数,由于模式不匹配,验证将失败,因为输入包含前导空格和尾随空格,但通过添加转换函数验证通道并同时清理字段值。
Messages
根据您的应用程序要求,您可能需要 i18n 支持,或者您可能更喜欢不同的验证错误消息。
实现此目的的最简单方法是为规则分配消息:
{
name: {
type: "string",
required: true,
message: "Name is required"
}
}消息可以是任何类型,例如 jsx 格式。
{
name: {
type: "string",
required: true,
message: <b>Name is required</b>
}
}您可能需要针对不同语言使用相同的架构验证规则,在这种情况下,复制每种语言的架构规则是没有意义的。在这种情况下,您只需提供自己的语言消息并将其分配给架构:
var schema = require('async-validator');
var cn = {
required: '%s 必填',
};
var descriptor = { name: { type: 'string', required: true } };
var validator = new schema(descriptor);
// deep merge with defaultMessages
validator.messages(cn);
// ...如果要定义自己的验证函数,最好将消息字符串分配给消息对象,然后通过验证函数中的 options.messages 属性访问消息。
validator
您可以自定义验证指定字段的功能:
const fields = {
asyncField: {
validator(rule, value, callback) {
ajax({
url: 'xx',
value: value,
}).then(
function(data) {
callback();
},
function(error) {
callback(new Error(error));
},
);
},
},
promiseField: {
validator(rule, value) {
return ajax({
url: 'xx',
value: value,
});
},
},
};