JSON Schema校验
Drip Form 协议底层使用 JSON Schema1规范 配合 Ajv2 校验。
使用 JSON Schema 的好处
- 确保表单数据的格式统一(避免冗余、格式错误数据的提交)
- 方便前后端统一校验函数
- 无需开发常见校验场景(JSON Schema 和 Ajv 已经提供)
- 描述数据的格式
使用 Ajv 的好处
少写代码
无需编写数据校验逻辑
使用简洁、易于阅读和跨平台的 JSON Schema 协议立即校验数据
超级快速和安全
Ajv 生成代码以将 JSON 模式转换为对 v8 优化有效的超快速验证函数。
目前 Ajv 是最快和最符合标准的验证器
支持多个 JSON Schema 草案
包括最新的 2020-12 草案
回顾
在《unitedSchema 协议 表单校验》文档中,我们学习以下内容
- 使用
requiredMsg、minItems、minmum、maximum校验关键字 - 使用
errMsg配置关键字错误文案
我们大致了解了如何使用 unitedSchema 配置校验。
接下来,我们将介绍 JSON Schema1和 ajv2插件提供的关键字。
提示
number
倍数
multipleOf JSON Schema
- 例子1
- 例子2
{
"type": "number",
"multipleOf": 10
}
- 校验通过:
10、20 - 校验失败:
11
{
"type": "number",
"multipleOf": 2.5
}
- 校验通过:
2.5、5、7.5 - 校验失败:
11
范围
maximum/minimum JSON Schema
- maximum例子
- minimum例子
{
"type": "number",
"maximum": 10
}
- 校验通过:
1、9、10 - 校验失败:
11
{
"type": "number",
"minimum": 10
}
- 校验通过:
10、11 - 校验失败:
9
exclusiveMaximum/exclusiveMinmum JSON Schema
- exclusiveMaximum例子
- exclusiveMinmum例子
{
"type": "number",
"exclusiveMaximum": 10
}
- 校验通过:
1、9 - 校验失败:
10、11
{
"type": "number",
"exclusiveMinmum": 10
}
- 校验通过:
11、12 - 校验失败:
10、9
multipleOf JSON Schema
- 例子1
- 例子2
{
"type": "number",
"multipleOf": 10
}
- 校验通过:
10、20 - 校验失败:
11
{
"type": "number",
"multipleOf": 2.5
}
- 校验通过:
2.5、5、7.5 - 校验失败:
11
range Ajv
{
"type": "number",
"range": [2, 4]
}
- 校验通过:
2、3、4、2.3 - 校验失败:
1、5
exclusiveRange Ajv
{
"type": "number",
"exclusiveRange": [2, 4]
}
- 校验通过:
2.11、3、3.99 - 校验失败:
1、2、4、5
string
长度
minLength/maxLength JSON Schema
注意:这里不区分中英文长度,中英文长度均为1
{
"type": "string",
"minLength": 2,
"maxLength": 3
}
- 校验通过:
a我1、a我 - 校验失败:
我、我爱13
gbkLength Drip Form
区分中英文长度
{
"type": "string",
"gbkLength": {
"min": 2,
"max": 3
}
}
- 校验通过:
爱、爱1 - 校验失败:
1、我爱
rangeDelimiter Drip Form
使用分割符分割之后的最长最短输入校验。
{
"type": "string",
"rangeDelimiter": {
// 使用英文逗号分割字符串
"delimiter": ",",
// 分割之后的最多4位
"max": 4,
// 分割之后最少2位
"min": 2
}
}
- 校验通过:
"1,2,3,4"、"1,2,3"、"1,2" - 校验失败:
"1"、"1,2,3,4,5"
正则
pattern JSON Schema
pattern 的值是一个字符串,用于 new RegExp(value,"u")创建将用于测试数据的正则表达式
{
"type": "string",
"pattern": "[abc]+"
}
- 校验通过:"a"、"abcd"、"cde"
- 校验失败:"def"、""
regexp Ajv
此关键字允许在正则中使用带有标志的正则表达式,并且也可以不使用"u"标志(pattern默认存在"u"标志)
{
"type": "string",
"regexp": "/foo/i"
}
- 校验通过:
Food、foo - 校验失败:
fog
转换
transform Ajv
此关键字允许在验证期间修改字符串。
支持的转换:
- trim: 删除开头和结尾的空格
- trimStart/ trimLeft: 从开始删除空格
- trimEnd/ trimRight:从末尾删除空格
- toLowerCase: 转换为小写
- toUpperCase: 转换为大写
- 单个转换
- 多重转换
{
"type": "string",
"transform": ["trim"]
}
- 校验前:
" MixCase " - 校验后:
"MixCase"
转换按照列出的顺序应用。
{
"type": "string",
"transform": ["trim", "toLowerCase"]
}
- 校验前:
" MixCase " - 校验后:
"mixcase"
格式
format JSON Schema
此关键字提供了一些常见语义的校验。比如:日期、url、ip地址等
format 支持以下格式
- 日期和时间
- date-time
JSON Schema、Drip Form - time
JSON Schema - date
JSON Schema - duration
JSON Schema - iso-time
Ajv - iso-date-time
Ajv
- date-time
- 电子邮件地址
- email
JSON Schema - idn-email
JSON Schema
- email
- 主机名
- hostname
JSON Schema - idn-hostname
JSON Schema
- hostname
- ip 地址
- ipv4
JSON Schema - ipv6
JSON Schema
- ipv4
- 资源标识符
- uuid
JSON Schema - uri
JSON Schema - uri-reference
JSON Schema - iri
JSON Schema - iri-reference
JSON Schema - uri-template
Ajv - url
Ajv - https
Drip Form是否是规范的 https url
- uuid
- 其他
- regex
Ajv - json-pointer
Ajv - relative-json-pointer
Ajv - byte
Ajv - int32
Ajv - int64
Ajv - float
Ajv - double
Ajv - password
Ajv - binary
Ajv - color
Drip Form是否是颜色字符串(支持 rgba、rgb、hex 三种颜色) - jsonObject
Drip Form是否是 json 对象字符串
- regex
array
长度
minItems/maxItems JSON Schema
{
"type": "array",
"minItems": 2,
"maxItems": 3
}
- 校验通过:
[1,2]、[1,2,3] - 校验失败:
[1]、[1,2,3,4]
唯一性
uniqueItems JSON Schema
{
"type": "array",
"uniqueItems": true
}
- 校验通过:
[1,2]、[1,2,3] - 校验失败:
[1,2,1]、[{a: 1,b: 2},{b: 2,a: 1}]
uniqueItemProperties Ajv
{
"type": "array",
"uniqueItemProperties": ["id", "name"]
}
校验通过:
[{id: 1},{id: 2},{id: 3}]校验失败:
- 失败例子1
- 失败例子2
[
{id: 1},
{id: 1}, // duplicate "id"
{id: 3},
][
{id: 1, name: "taco"},
{id: 2, name: "taco"}, // duplicate "name"
{id: 3, name: "salsa"},
]
子项
items JSON Schema
- 普通数组
- 元祖
普通数组是指数组中每一项数据格式一致的数组。比如:[1,2,3]、['1','2','3']、[{a:1},{a:2}]
{
"type": "array",
"items": {
"type": "string"
}
}
- 校验通过:
[]、['1','2'] - 校验失败:
[1]
元祖是指数组有固定顺序和长度限制,且格式不一致。比如:[1,'2']
{
"type": "array",
"minItems": 2,
"additionalItems": false,
"items": [
{
"type": "string"
},
{
"type": "number"
}
]
}
- 校验通过:
['1',2]、['3',4] - 校验失败:
[1,2]
额外项
additionalItems JSON Schema
- 不允许存在多余子项
- 允许存在多余子项,不限制子项类型
- 允许存在多余子项,限制子项类型
{
type: "array",
items: [{type: "number"}, {type: "string"}],
minItems: 2
additionalItems: false
}
- 校验通过:
[1,'2'] - 校验失败:
[]、[1]、[1,'2',3]、[1,2]
{
type: "array",
items: [{type: "number"}, {type: "number"}],
additionalItems: true
}
- 校验通过:
[]、[1, 2]、[1, 2, 3]、[1, 2, "abc"] - 校验失败:
["abc"]、[1, "abc", 3]
{
type: "array",
items: [{type: "number"}, {type: "number"}],
additionalItems: {type: "string"}
}
- 校验通过:
[]、[1, 2]、[1, 2, "abc"] - 校验失败:
["abc"]、[1, 2, 3]
包含
contains JSON Schema
{
"type": "array",
"contains": {
"type": "number"
}
}
- 校验通过:
[1]、[1, "foo"](任何至少有一个整数的数组) - 校验失败:
[]、["foo", "bar"](没有任何整数的数组)
maxContaines/minContains JSON Schema
{
type: "array",
contains: {type: "number"},
minContains: 2,
maxContains: 3
}
- 校验通过:
[1, 2]、[1, 2, 3, "foo"](任何有 2 或 3 个整数的数组) - 校验失败:
[]、[1, "foo"]、[1, 2, 3, 4](任何少于 2 个或多于 3 个整数的数组)
object
属性
properties JSON Schema
{
type: "object",
properties: {
foo: {type: "string"},
bar: {
type: "number",
minimum: 2
}
}
}
- 校验通过:
{}、{foo: "a"}、{foo: "a", bar: 2}、{foo:'a',bar:2,c:3}(省略、多余属性均不影响) - 校验失败:
{foo: 1}、{foo: "a", bar: 1}
正则属性
patternProperties JSON Schema
{
type: "object",
patternProperties: {
"^fo.*$": {type: "string"},
"^ba.*$": {type: "number"}
}
}
- 校验通过:
{}、{foo: "a"}、{foo: "a", bar: 1} - 校验失败:
{foo: 1}、{foo: "a", bar: "b"}
额外属性
additionalProperties JSON Schema
- 不允许存在多余子属性
- 允许存在多余子属性,不限制子属性类型
- 允许存在多余子属性,限制子属性类型
{
type: "object",
properties: {
foo: {type: "number"}
},
additionalProperties: false
}
- 校验通过:
{}、{foo:1} - 校验失败:
{a:3}、{foo:1,a:3}
默认additionalItems为true,即不限制额外的属性
{
type: "object",
properties: {
foo: {type: "string"},
bar: {
type: "number",
minimum: 2
}
},
//可省略additionalItems
additionalItems:true
}
- 校验通过:
{}、{foo: "a"}、{foo: "a", bar: 2}、{foo:'a',bar:2,c:3}(省略、多余属性均不影响) - 校验失败:
{foo: 1}、{foo: "a", bar: 1}
{ type: "object", properties: { foo: {type: "number"} }, additionalProperties: {type: "string"} }
- 校验通过:
{}、{a: "b"}、{foo: 1}、{foo: 1, bar: 2}、{foo: 1, bar: 2, a: "b"} - 校验失败:
{a: 3}、{foo: 1, baz: 3}
prohibited Ajv
禁止列表中的任何属性出现在对象中。
{
type: "object",
prohibited: ["foo", "bar"],
}
- 校验通过:
{baz: 1}、{} - 校验失败:
{foo: 1}、{bar: 2}、{foo: 1, bar: 2}
必须属性
requriedMsg Drip Form
设置对象中某个属性必填,参考[表单校验 必填](../../unitedSchema/schemaKeyword#必填)
allRequired Ajv
所有属性均要出现在对象中。
{
type: "object",
properties: {
foo: {type: "number"},
bar: {type: "number"},
},
allRequired: true,
}
- 校验通过:
{foo: 1, bar: 2}、{foo: 1, bar: 2, baz: 3} - 校验失败:
{foo: 1}、{bar: 2}、{}
anyRequired Ajv
至少一个属性要出现在对象中。
{
type: "object",
anyRequired: ["foo", "bar"],
}
- 校验通过:
{foo: 1}、{foo: 1, bar: 2} - 校验失败:
{}、{baz: 3}
oneRequired Ajv
只有一个属性出现在对象中。
{
type: "object",
oneRequired: ["foo", "bar"],
}
- 校验通过:
{foo: 1}、{bar: 2, baz: 3} - 校验失败:
{}、{baz: 3}、{foo: 1, bar: 2}
patternRequired Ajv
每个正则表达式都应至少匹配数据对象中的一个属性名称
{
type: "object",
patternRequired: ["f.*o", "b.*r"],
}
- 校验通过:
{foo: 1, bar: 2}、{foobar: 3} - 校验失败:
{}、{foo: 1}、{ bar: 2}
属性名称
propertyNames JSON Schema
对象中的每个属性名称都应根据此模式有效
{
type: "object",
propertyNames: {
format: "email"
}
}
- 校验通过:
{"foo@bar.com": "any", "bar@bar.com": "any"} - 校验失败:
{foo: "any value"}
大小
minProperties/maxProperties JSON Schema
对象中的每个属性名称都应根据此模式有效
{
type: "object",
minProperties: 2,
maxProperties: 3,
}
- 校验通过:
{a:1,b:2}、{a:1,b:2,c:3} - 校验失败:
{foo: "any value"}、{a:1,b:2,c:3,d:4}