背景
使用vue3+naive ui 开发网站,在写表单校验规则,其中URL校验项使用了regex
,表达式写的有问题,在校验某些URL出现卡顿。最后使用浏览器内置URL类
的构建函数来校验,放弃了正则。
REGEX探讨
/^(https?:\/\/)?([\da-z\.-]+)\.([a-z]{2,6})([\/\w \.-]*)*\/?$/.test('https://www.tt.com/km/123/456/1231212121.py?method=view&fdId=112233');
问题出在(\/[\w.-]*)*
这一段,它匹配的是/km/123/456/1231212121.py?method=view&fdId=112233
意思是将字符串按/
分开,匹配之后的[A-Za-z0-9_.-]
,遇到新的斜杠就开始新的一轮匹配。
即依次匹配/km
、/123
、/456
......
这个重复匹配斜杠开头没有问题,问题是后续的字符我限定的太少了,而这里有一个?
,导致匹配失败后会重新回溯,重新尝试匹配。
比如一开始匹配的是/km/123/456/1231212121.py
,遇到问号,觉得有问题,重新匹配到/km/123/456
,然后后面的字符交给后续的表达式匹配。
我想到的解决方法就是直接匹配斜杠开头+任意字符:
/^(https?:\/\/)?([\da-z\.-]+)\.([a-z]{2,6})\/.*/.test('https://www.tt.com/km/123/456/1231212121.py?method=view&fdId=112233');
浏览器内置URL类探讨
export function checkUrl(url) {try {new URL(url);return true;} catch (e) {return false;}
}
当时是询问AI有没有其他的校验方法,比较中意的就是这个。但是这个URL类是浏览器内置的API,我需要确定一下它的构建函数是怎么校验url的。
如何确认URL是内置API
console.log(URL)
output: ƒ URL()
说明就是浏览器的API
确认URL构造函数内容
需要去翻阅浏览器源码
这里参照[chromuim/url](chromium/url at main · chromium/chromium)
阅读readme可以发现是由c++实现的gurl
,对js环境表现为URL
校验内容:
scheme(即'http'等前缀) 和 host/path/query
是否有合法的 scheme →
DoExtractScheme()
是否属于 special 协议 →
IsStandard()
是否能成功拆解 host/path/query →
DoParseAuthority()
+ParsePath()
是否嵌套结构合法(NoStandardUrl会考虑) →
DoParseFileSystemURL()
最终由
Canonicalize()
返回is_valid_
,决定 GURL 是否有效