看不见的字符

1,968 阅读2分钟

一.问题背景

h5有个表单需要填写手机号提交,有一个库里的订单列表需要根据手机号查询某个订单,根据填写的手机号无法查询订单。先经后端排查发现,该手机号含有有问题的字符,于是猜测前端入口录入时没有进行手机号校验,或校验规则不正确,导致出现全角字符,最终导致数据库无法匹配到数据。

二.前端排查

1.神奇的字符

13728510798‬

'13728510798‬'.length
//12

/^1\d{10}$/.test('13728510798'‬)
//报错:Uncaught SyntaxError: missing ) after argument list


Number('13728510798‬')
//NaN

因为是移动端,唤起的是纯数字键盘,正常输入是不会有问题的,那可能就是不知道从哪复制粘贴的了,先不管数据来源,下面看一下前端代码

2.看前端校验代码

前端代码一切正常

正常的input

<input type="number" v-model="phone">

正常的11位数字正则校验

/^1\d{10}$/.test(phone)

这个字符串明明是没通过该正则校验的

image

3.有问题字符明明没有通过正则校验,却在前端表单里提交成功

原来,input标签在type=“number”时会自动将该问题字符串过滤成正常的11位纯数字,因此可以通过校验,也就说明,哪怕用户是不知道从哪复制有问题的数据粘贴到表单的input输入框,前端传给后台的数据也是没有问题的。

但是我试验了一下,发现如果去掉type="number",那么这个问题字符串就实实在在的通过不了正则校验了。

那么哪里来的这个数据呢?可能就是人工复制粘贴导入数据造成的脏数据把。

三.搞清楚了

原来一直以为8有问题,因为发现按一次删除键,光标还在8的右边,以为8占两个字符。后来,后端给我看了这个字符串的unicode编码,才恍然顿悟。 原来,这个8的编码后面还有一个编码,也就是说8后面还有一个看不见的字符

\u0031\u0033\u0037\u0032\u0038\u0035\u0031\u0030\u0037\u0039\u0038

四.如何处理这种问题字符串呢?

参考大神同事分享的文章,可以用字符替换,把问题字符过滤掉 note.youdao.com/noteshare?i…

var str='13728510798‬';var a=str.replace("\u0038", "");console.log(a)
//大功告成