|
vue项目里,正则过过滤IP地址这事,滤掉看着简单,地址真做起来坑不少。正则过正则写对了,滤掉能省一大半事,地址写错了,正则过用户填个IPv6或者带端口的滤掉地址,直接给你报错弹窗,地址体验瞬间拉胯。正则过 先说我遇到的滤掉实际场景。后台管理系统里有个输入框,地址要校验用户填的正则过服务器地址,只允许IPv4。滤掉第一版我直接用了网上抄来的地址正则:/^(\d{ 1,3}\.){ 3}\d{ 1,3}$/。测的时候发现,999.999.999.999这种鬼东西也能通过——因为\d{ 1,3}只限制位数,不限制数值范围。这不行,得把每段数字卡死在0到255之间。 正确的IPv4正则长这样:/^((25[0-5]|2[0-4]\d|1\d{ 2}|[1-9]?\d)\.){ 3}(25[0-5]|2[0-4]\d|1\d{ 2}|[1-9]?\d)$/。看着吓人,拆开就明白:25[0-5]管250-255,2[0-4]\d管200-249,1\d{ 2}管100-199,[1-9]?\d管0-99。四段一样的规则,用点号连接,首尾加锚点防止部分匹配。 但光校验格式还不够。用户可能粘贴个带空格的地址,或者末尾多个回车。所以过滤前得先trim()一下。还有的人会填192.168.1.1:8080这种带端口的,这时候你如果只做IP校验,直接判非法。合理做法是先拆端口再校验,或者干脆提示用户分开填。 vue里写过滤逻辑,我习惯放在computed或者watch里,而不是直接在模板里写正则。比如有个inputValue,实时过滤非法字符,可以这样: filteredValue() { return this.inputValue.replace(/[^\d.]/g, '') } 这行代码把非数字和点号的字符全删了,用户输字母、空格、特殊符号,直接消失。但有个问题——用户输入1.2.3.4.5这种多段点号,不会被拦截。真要严格,得配合失焦时的完整校验,或者用带状态机的正则做实时约束,不过那样代码量就上去了。 还有个细节容易被忽略:IPv6。现在不少公司内网开始用IPv6了,如果你的输入框只认IPv4,用户填个2001:db8::1,直接判非法——这没毛病,但如果业务上需要兼容,得写两套正则切换。我见过一个项目,前端只校验IPv4,后端返回IPv6地址,结果列表页显示全被截断,排查半天才发现是过滤正则把冒号当非法字符删了。 另外,别把正则写死。用new RegExp()动态构造,方便后续改规则。比如IP段限制从0-255改成0-999(虽然不标准,但有些内网工具真这么干),你只需要改一段字符串,不用动整个逻辑。 最后说个土办法,但很实用——如果只是要过滤输入,不让用户乱填,可以监听keydown事件,判断按键是不是数字或点号,不是就preventDefault()。这比正则实时匹配更直接,用户连粘贴非法内容的机会都没有。但注意,移动端软键盘的按键事件有时不触发,所以还是得留一手正则兜底。 过滤IP这事,没有银弹。格式校验只是第一关,真正重要的是想清楚业务上允许什么、拒绝什么。正则写得再漂亮,不如提前跟产品确认清楚:要不要支持IPv6?端口号怎么处理?空值算不算合法?这些问明白了,代码反而简单。 |