记一次IOS通讯录拷贝出的号码含有不可见字符的bug - pod4g/tool GitHub Wiki
一、背景
有一个电话号码输入框
由于从IOS通讯录中拷贝的电话号码138 0000 8888
是有空格分割的,所以需要把空格干掉,变成纯净的电话号码13800008888
,不然通不过/^\d{11}&/
的校验
二、去掉空格的方法
function trimAll(str) {
return str.replace(/\s*/g, '');
}
三、bug现身
后面发现,在IOS11.2中,空格已经被干掉了,但是校验时,还是通不过。说明这个看起来干净的号码中一定含有不可见的字符。。
验证:
'13800008888'.length === 13
Unicode转码:\u202d13800008888\u202c
可以看到前后个出现了一个非法字符
四、修复
经过查询资料,发现这是Unicode控制字符,Unicode控制字符较多,\u061C\u200E\u200F\u202A\u202B\u202C\u202D\u202E\u2066\u2067\u2068\u2069
属于【双向文本控制】字符,拷贝时可能会带有【双向文本控制】字符,故每个都要处理
function trimAll(str) {
return str.replace(/[\u061C\u200E\u200F\u202A\u202B\u202C\u202D\u202E\u2066\u2067\u2068\u2069\s]*/g, '');
}
五、后续的思考
更好的处理方式
等这个bug修复并上线以后,我才想到一个更好的办法
function trimAll(str) {
// 干掉所有非数字字符即可,没必要一个个罗列Unicode控制字符,因为语义上来说,手机号码肯定都是数字
return str.replace(/\D/g, '');
}
- 自己解决这个问题用了一天的时间,用时过长,只是直觉上认为号码中有不可见字符,而不是通过
'13800008888'.length === 13
验证一下, 没有聪明劲