记去年九月份的一次 bug 修复经历
背景
线上某页面,某用户手机(iPhone7)上有问题,问题页面在我们自己的 APP 中,用户进入该页面,什么操作都做不了;从用户发来的截图看,页面上动态查询的数据也没有显示;
定位
后端查日志,发现该用户的 ajax 请求没有发过来;
这种情况,肯定是某句代码报错,导致后边的代码没执行;一般报错可能是:
- 对象为空,但是调用了对象上的方法;
- 数组为 null,但是按下标取了值;
- 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 的情况,虽然非空判断有些麻烦,但还是要做足;