如何使用Joi Validation实现YouTube视频ID字段禁止输入URI的校验规则
解决方案
方式1:使用Joi内置when规则实现(推荐,无需自定义逻辑)
直接利用when判断值是否符合URI格式,符合则标记为禁止:
youtubeVideoId: Joi.string() .label('YouTube Video ID') .allow(null) .allow('') .when(Joi.string().uri(), { then: Joi.forbidden().message('不可输入完整URI,请仅填写YouTube Video ID') })
如果需要额外禁止字段包含http、www这类URI特征子串,可以再加一条pattern规则:
youtubeVideoId: Joi.string() .label('YouTube Video ID') .allow(null) .allow('') .pattern(/http|www/i, { invert: true, message: '不可包含URI相关特征字符,请仅填写YouTube Video ID' }) .when(Joi.string().uri(), { then: Joi.forbidden().message('不可输入完整URI,请仅填写YouTube Video ID') })
方式2:使用custom自定义校验实现(更灵活,可扩展更多校验逻辑)
如果后续还要对Video ID的格式做额外校验,可以用自定义函数实现:
youtubeVideoId: Joi.string() .label('YouTube Video ID') .allow(null) .allow('') .custom((value, helpers) => { // 空值直接通过校验 if (!value) return value; // 校验当前值是否为合法URI const { error } = Joi.string().uri().validate(value); if (!error) { return helpers.error('any.invalid', { message: '不可输入完整URI,请仅填写YouTube Video ID' }); } return value; })
原有写法失效原因
- 第一种写法的
invalid('http', 'www')仅会拦截完全等于http或www的字符串,不会判断字符串是否包含对应子串,因此不生效。 - 第二种写法的
invalid(Joi.string().uri())中的invalid方法仅做全等匹配,不会将传入的Joi schema作为规则校验值,因此无法拦截URI格式内容。
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

