Joi .or()函数未按预期工作:需至少填写两个字段之一
解决Joi .or() 未按预期生效的问题
问题原因
你当前的代码中,either-this-field和or-this-field是可选字符串字段,但Joi默认会把空字符串视为有效的字段值(而非“未提供”)。当两个字段都填为空时,.or()会认为两个字段都存在,因此不会触发“至少填一个”的校验规则,只会执行各自的字符串校验(而空字符串符合.string().trim().max(26)的规则,因为没有限制非空)。
修复方案
给两个字段添加.empty(''),将空字符串转换为undefined(等同于未提供该字段),这样.or()就能正确检测是否至少有一个字段被填写。同时可以自定义错误提示,让用户明确知道需要至少填其中一个。
修改后的代码:
const schema = joi .object({ "either-this-field": joi.string().trim().max(26).empty(''), "or-this-field": joi .string() .trim() .regex(/^\d+$/) .max(26) .empty(''), "other-field-1": joi.string().required(), "other-field-2": joi.string().max(40).required(), }) .or("either-this-field", "or-this-field") .messages({ 'object.or': '请填写「either-this-field」或「or-this-field」中的至少一个' });
额外说明
.empty(''):告诉Joi把空字符串当作undefined处理,这样未填写或填了空内容的字段会被视为“未提供”,触发.or()的校验逻辑。- 如果需要严格禁止空字符串(即填写了就必须是非空的),可以在两个字段的规则里加上
.min(1),比如:
这样既保证填写时内容非空,又能让空输入触发"either-this-field": joi.string().trim().min(1).max(26).empty(''),.or()的校验。
内容的提问来源于stack exchange,提问作者Sandy Garrido
相关产品推荐
相关产品推荐

