AJV 5.5.1必填字段验证疑问:空字符串未触发校验失败
解决AJV 5.5.1中必填字段与空值校验的问题
我来帮你理清AJV里必填字段的逻辑,以及如何实现你想要的校验效果——首先得明确JSON Schema(以及AJV)中required关键字的核心作用:它只检查属性是否存在于对象中,而不关心属性值是否为空或有效。这就是为什么你传{ name: '' }时校验通过的原因:name属性存在,且空字符串符合type: string的要求;而传null时,因为null不是字符串类型,所以触发类型错误,而非必填错误。
要实现「属性无值时校验失败」+「区分必填错误与类型/空值错误」的需求,可以按以下步骤调整:
1. 给字符串属性添加minLength规则,拒绝空字符串
要让空字符串''也不通过校验,只需在name的schema中添加minLength: 1——这个关键字会强制字符串长度至少为1,直接拦截空值。修改后的schema如下:
const schema = { 'required': [ 'name' ], 'type': 'object', 'properties': { 'name': { 'type': 'string', 'minLength': 1 // 新增:禁止空字符串 } } };
2. 通过错误对象的keyword字段区分错误类型
AJV的错误数组(validator.errors)中,每个错误对象都包含keyword字段,你可以通过这个字段精准区分不同类型的错误:
- 必填错误:
keyword值为"required",对应属性完全未传入的场景(比如{}) - 类型错误:
keyword值为"type",对应属性值类型不符合要求的场景(比如{ name: null }) - 空字符串错误:
keyword值为"minLength",对应属性存在但为空字符串的场景(比如{ name: '' })
完整测试示例
下面是包含三种场景的完整代码,你可以直接运行验证:
const opt = { $data: true, allErrors: true, verbose: true, unknownFormats: ['int32', 'int64', 'double'] }; opt['v5'] = true; const validator = withKeywords(new Ajv(opt), ['switch', 'if']); withError(validator); const schema = { 'required': [ 'name' ], 'type': 'object', 'properties': { 'name': { 'type': 'string', 'minLength': 1 } } }; // 场景1:未传入name属性(必填错误) const data1 = {}; const isValid1 = validator.validate(schema, data1); console.log('场景1校验结果:', isValid1); // false console.log('场景1错误类型:', validator.errors[0].keyword); // "required" // 场景2:name为空字符串(minLength错误) const data2 = { name: '' }; const isValid2 = validator.validate(schema, data2); console.log('场景2校验结果:', isValid2); // false console.log('场景2错误类型:', validator.errors[0].keyword); // "minLength" // 场景3:name为null(类型错误) const data3 = { name: null }; const isValid3 = validator.validate(schema, data3); console.log('场景3校验结果:', isValid3); // false console.log('场景3错误类型:', validator.errors[0].keyword); // "type"
补充说明
- 你的AJV 5.5.1版本完全支持
minLength关键字,无需担心兼容性问题 - 如果需要更严格的校验(比如拒绝全空格的字符串),可以额外添加
pattern: '\\S+'规则,确保字符串包含至少一个非空白字符
内容的提问来源于stack exchange,提问作者aleczandru
相关产品推荐
相关产品推荐

