JSON Schema校验
Drip Form
协议底层使用 JSON Schema
1规范 配合 Ajv
2 校验。
使用 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}