Ajv验证未检测出uri格式违规问题排查
问题原因与解决方法
默认URI验证规则过松:ajv-formats v2.x 默认的
uri格式验证采用RFC 3986的宽松解析逻辑,允许部分在严格场景下不合法的字符(比如你示例中域名部分的=),因此不会触发验证失败。而部分在线工具使用了更严格的验证规则,所以能检测到该错误。解决步骤:
- 启用严格模式验证:ajv-formats提供了
mode: "strict"选项,注册格式时开启即可切换到更严格的验证逻辑,示例代码如下:const Ajv = require("ajv"); const addFormats = require("ajv-formats"); const ajv = new Ajv(); // 开启严格模式注册格式 addFormats(ajv, { mode: "strict" }); const schema = { type: "object", properties: { a: { type: "string", format: "uri" } } }; const validate = ajv.compile(schema); const myData = { a: "https://a.=.c" }; const isValid = validate(myData); console.log(isValid); // 此时会返回false console.log(validate.errors); // 输出对应的格式错误信息 - 自定义验证逻辑:如果严格模式仍不符合需求,可自定义URI验证函数注册到Ajv中,比如结合
URLAPI和额外的域名合法性检查:const Ajv = require("ajv"); const ajv = new Ajv(); // 自定义严格URI验证格式 ajv.addFormat("strict-uri", { type: "string", validate: (str) => { try { const url = new URL(str); // 检查域名是否包含非法字符 return !/[^a-zA-Z0-9.-]/.test(url.hostname); } catch (e) { return false; } } }); const schema = { type: "object", properties: { a: { type: "string", format: "strict-uri" } } }; const validate = ajv.compile(schema); const myData = { a: "https://a.=.c" }; console.log(validate(myData)); // 返回false
- 启用严格模式验证:ajv-formats提供了
补充说明:ajv-formats支持三种模式:默认的
fast(宽松解析)、strict(严格遵循RFC规范)、full(包含更多额外格式检查),可根据需求选择对应模式。
内容的提问来源于stack exchange,提问作者Marue
相关产品推荐
相关产品推荐

