Fastclick的“Bug”

记去年九月份的一次 bug 修复经历

背景

线上某页面,某用户手机(iPhone7)上有问题,问题页面在我们自己的 APP 中,用户进入该页面,什么操作都做不了;从用户发来的截图看,页面上动态查询的数据也没有显示;

定位

后端查日志,发现该用户的 ajax 请求没有发过来;

这种情况,肯定是某句代码报错,导致后边的代码没执行;一般报错可能是:

  1. 对象为空,但是调用了对象上的方法;
  2. 数组为 null,但是按下标取了值;
  3. JSON.parse 的参数不是一个 json 串;

逐句代码检查,ajax 请求之前的代码非常多,查了好久,但并未发现有什么问题;

后端又发来了用户的 ua,里边好多自定义串,是 APP 加进去的;突然想到是否 ua 中的加了一些特殊字符,导致从 ua 中取值做判断的逻辑出错了呢;

又查使用 ua 的地方,自己的代码中也没有查到;

这样就只剩下第三方的公共库了,页面只引了两个第三方代码,一个是 zepto,一个是 fastclick;分别找到他们的源码,搜使用 ua 的地方,终于找到了问题;

ua 中有一个特殊的字符串 “BB10″,fastclick 中用这个串来判断是否为黑莓手机,然后进入了一个分支,分支里边有一个地方没有做非空判断,就报错了;

解决

fastclick 中的相关代码如下:

var deviceIsBlackBerry10 = navigator.userAgent.indexOf('BB10') > 0;
// …… 其他代码
if (deviceIsBlackBerry10) {
    blackberryVersion = navigator.userAgent.match(/Version\/([0-9]*)\.([0-9]*)/);
    // BlackBerry 10.3+ does not require Fastclick library.
    // http://github.com/ftlabs/fastclick/issues/251
    if (blackberryVersion[1] >= 10 && blackberryVersion[2] >= 3){
        // …… 其他代码

这段代码的 if 分支中,没有判断 blackberryVersion 是否为空,就直接当做数组做了取值操作;加一个非空判断就可以了:

 if (blackberryVersion && blackberryVersion[1] >= 10 && blackberryVersion[2] >= 3){

总结

APP 和 fastclick 两方都有问题吧;

APP 开发:ua 尽量不要乱加东西,本实例中,app 往 ua 中加的东西非常多,除了一些固定的 app 标识字符串,还往 ua 中添加了用户标识字符串,用户标识串是根据用户登录信息和手机型号生成的,每个用户的 ua 不一样;用户标识串这个就有点儿过了,虽然是根据某些算法生成的类随机字符串,但不能保证里边没有其他类型手机的标识串;比如安卓手机里,生成了一个“ipad”、“iphone”……

fastclick:只考虑了固定 ua 的情况,虽然非空判断有些麻烦,但还是要做足;

如果这篇文章对你有用,可以点击下面的按钮告诉我

0

发表回复