阅读 944

IOS 11 通讯录手机号「隐形字符」的 Bug,Apple 真的不打算修复了吗?

原文链接: github.com

前言

9月中旬,很多朋友反映,微信不能通过手机号搜到好友了。。

试了下,好像从通讯录里复制过来的手机号确实存在不匹配的问题。是微信的锅?

问了下度娘。给出「答案」。

看到这个答案,我想说:真扯!

下面咱们来把他「打回原形」。

都是 IOS 的锅

先把微信放一边,来试试其他 App,结果只要是涉及到输入手机号的基本都沦陷了(使用场景最多的就是手机号绑定、登录、验证等页面),我们拿BATN来做测试

百度

支付宝

淘宝

百度,猫厂的支付宝和淘宝,猪厂的考拉和严选(找不到图了),都存在相同的问题(猪厂已修复,猫厂和百度目前还存在问题,或许是寄希望于 IOS 自己修复吧,IOS 11 的小伙伴可以自己实验一把)

BATN 都沦陷了,看来是 IOS 的锅了。

看不见的字符

找到问题所在,我们就来一探究竟。我们准备了一个功能单一的页面,打印输出通讯录复制过来的字符串到底是个什么鬼!

由下面两张图,我们可以「看到」一些看不到的字符

我们来看:号码「130 5755 xxxx」长度 15 ?!就算加上空格也才 13,肿么就 15 了?!这不科学啊?!

我们再来看下 URI 编码结果:「%E2%80%AD130%205755%207808%E2%80%AC」,有没有发现问题?
%E2%80%AD, %E2%80%AC是什么鬼?

我们知道,通过 encodeURIComponent 可把字符串作为 URI 组件进行编码,但不会对 ASCII 的字母、数字和- _ . ! ~ * ' ( ) 这些特殊的字符进行编码,其余的全部使用十六进制编码表示,如空格将被转换为 %20,但 %E2%80%AD%E2%80%AC 是从什么转换过来的就有意思了,一个「三字节」、「看不见」且「不占空间」的字符!

他不像「空格」和「换行」这类字符,虽然看不到,但是占空间,用户很容易明白,「手机号格式不正确」指的是什么。但是如果看不见了,用户将会一脸懵逼,甩出一句「什么破系统」,然后扬长而去。

这样可不行!

IOS 是不打算修了吗?

对于我们产品方,修还是不修,就看这个 Bug 的影响程度了,严重影响用户使用那就需要 HotFix,像微信,老早就修复了,因为对于微信来讲,复制通讯录手机号进行查询好友还是很普遍的场景。而对于登录为主的 App 就可以暂时不修,等待 IOS 系统自己修复即可,谁会每次登录去复制自己的手机号呢?对不对?

关于这个问题,估计很多公司都有反馈给 Apple 开发团队,就等他们发包更新了。

然而,漫长的等待换来的确是变本加厉。

11 月 10 日,IOS 11.1.1 版本正式发布。

激动地我赶紧试了一把(虽然老早我就想滚回 10.* 版本了)。

关于通讯录,Apple Team 确实做了优化,复制出来的号码贴心地加了国际区号「+86 130 5755 xxxx」,然而结果却让人失望。成功地由 2 个不可见字符变成了 4 个!

看样子,Apple Team 是不准备修复这个问题了。

好吧,只能我们乖乖的适配吧,谁叫人家是老大呢。

兼容方案

在以前,我们不推荐对手机号输入框等基础组件做过多的设计,以保持基础组件的单一功能。比如,自动去空格、去特殊字符、禁止粘贴、限制输入字符、限制长度等。

然而,针对 IOS 11 的这个 Bug,我们就必须做一件事,就是去除不可见且不占空的字符,但是由于实现起来难免会有遗漏,所以推荐使用数字提取。

可以在 oninput 时对数字字符进行提取,也可以在获取组件触发 get 时进行处理。

<input type="text" oninput="javascript:this.value=this.value.replace(/[^\d]/g,'')" />复制代码

也可以是

Vue.component('MobileInput', {
    template: '<input ref='ipt' v-model="val" />',
    methods: {
        getValue: function () {
            this.val = this.val.replace(/[^\d]/g,'');
            return this.val;
        }
    }
})
复制代码

但是,不管怎样,我们的原则是,必须让用户感知处理的结果。避免不必要的解释。

转载请标明出处
作者:木羽 zwwill
首发地址:#12