前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >跟进一个 jserror 问题带来的思考

跟进一个 jserror 问题带来的思考

原创
作者头像
serena
修改2021-08-03 14:56:09
1.2K10
修改2021-08-03 14:56:09
举报
文章被收录于专栏:社区的朋友们

作者:徐杰

wns-cgi的业务使用同学反馈了一个问题:在安卓手Q的空间里,打开小游戏,然后进入空间宠物,聊天窗口,发送消息。这里会注册一个jsbridge回调,发送消息后,回调后,小游戏页面会报一个js的error,比较奇怪,报错截图如下

报错信息倒是很明确,是因为方法未定义导致的异常;触发条件是因为宠物聊天用的是wns-cgi,所以最初怀疑是否和wns-cgi有关,就由我和xixinhuang一起在跟进这个问题;庆幸的是问题必现,这样我们就可以复现和构造各种场景;下面简单总结下定位的过程:A打开了B页面,B页面用了wns-cgi进行聊天(打开了输入法控制面板),B页面没出现异常,但是A页面的jserror报错了;

(1)根据报错信息最初是想确认为什么A页面会收到这个回调?明明是在B页面的操作啊?于是赶紧拉上了客户端同学和mqq.js的开发同学进行定位,可是没有什么头绪和进展,客户端同学觉得没问题啊,调用wns-cgi,客户端正常的执行了一段回调;wns-cgi的请求对象如下:

代码语言:javascript
复制
{"method":"post","url":"http://h5.qzone.qq.com/webapp/json/pet_chat/Chat?uin=2577199125&g_tk=830846970&t=0.36583463430175467","body":{"qua":"V1_AND_SQ_7.2.5_0_RDM_B","iEventID":2,"stCommInfo.lLoginUin":2577199125,"stCommInfo.lHostUin":2577199125,"stCommInfo.stGeoInfo.lLon":113933731,"stCommInfo.stGeoInfo.lLat":22540520,"stCommInfo.stGeoInfo.lAlt":0,"stCommInfo.strQua":"V1_AND_SQ_7.2.5_0_RDM_B","strText":"好红红火火恍恍惚惚","mapExtInfo.source":"h5","mapExtInfo.gpstype":"1","mapExtInfo.devicetype":"1","mapExtInfo.device_info":"","mapExtInfo.userPetId":10116,"mapExtInfo.hostPetId":10116,"mapExtInfo.first_sentence_id":"","strCookie":""},"timeout":0,"dataNeedBase64":false,"callback":"__MQQ_CALLBACK_AUTO_35"} 客户端

客户端处理后,loadurl调用的js代码如下:

代码语言:javascript
复制
(window.mqq && mqq.version > 20140616001 && mqq.execGlobalCallback||function(cb) {window[cb] && window[cb].apply(window, [].slice.call(arguments, 1));}).apply(window, ["__MQQ_CALLBACK_AUTO_35", {"status":4,"url":"http:\/\/h5.qzone.qq.com\/webapp\/json\/pet_chat\/Chat?uin=2577199125&g_tk=830846970&t=0.36583463430175467","code":0,"dataIsBase64":false,"data":"{\"ret\":0,\"msg\":\"\",\"data\":{\"stActionSet\":{\"iID\":0,\"vecActionInfo\":[{\"vecActionNode\":[{\"vecName\":[\"f_speak\"],\"iLoopCount\":1,\"fSpeed\":1}],\"stContentInfo\":{\"iContentType\":1,\"strText\":\"小宠的语文阔是数学老师教的哦~ 诗词歌赋样样精通!你想考我吗!\",\"strUrl\":\"\",\"vecChoice\":[],\"iStayTimeMs\":-1,\"stFile\":{\"iFileId\":0,\"strName\":\"\",\"strUrl\":\"\",\"strMd5\":\"\",\"iSize\":0,\"iFileType\":0,\"iWidth\":0,\"iHeight\":0},\"stUgcVideo\":{\"strVideoId\":\"\",\"iAppId\":0,\"iVideoWidth\":0,\"iVideoHeight\":0,\"iOperateMask\":0,\"iVideoState\":0,\"uiDurationTimeMs\":0,\"strVideoUrl\":\"\",\"strCoverImgUrl\":\"\",\"iCoverWidth\":0,\"iCoverHeight\":0,\"strOrgKey\":\"\",\"strCurKey\":\"\",\"strCid\":\"\",\"strUgcKey\":\"\",\"lUin\":0,\"strNick\":\"\"},\"vecPetQuickCommentPic\":[],\"stRelationChain\":{\"iTotal\":0,\"vecFriInfo\":[]},\"stFmInfo\":{\"strShowId\":\"\",\"strShowName\":\"\",\"strAudioUrl\":\"\",\"strCoverUrl\":\"\",\"strOwner\":\"\",\"iShowDuration\":0,\"strShowUrl\":\"\"}},\"strTrace\":\"\",\"iDelayMs\":0}]},\"mapExtInfo\":{},\"stValidator\":{\"lUin\":2577199125,\"strModelKey\":\"mao_phase1_20172217\"},\"strCookie\":\"chat_session_id=0A9E20724B9A4AF28A0CECA0BE2FC8CF\"}}","httpStatusCode":200,"header":{"x-powered-by":"TSW\/Node.js","cache-control":"no-cache","connection":"keep-alive","keep-alive":"timeout=10","vary":"Origin, Accept","mod-map":"webapp_json","content-type":"application\/json; charset=UTF-8","content-length":"1082","date":"Wed, 13 Sep 2017 07"}}]);

看起来调用wns-cgi没啥问题啊,问题重新回到了我们这边;

(2)我和xixin同学开始了错误的重新定位过程,既然报错是来自A页面,一定是和mqq的什么事件监听有关,之前我处理过mqq.debug.js文件,先定位到和这个错误有关的代码,是在invokeClientMethod中注册的,如下图:

那我们代理上这个mqq.js,然后在这个方法中加上console.trace()看看调用栈,会不会有帮助?

同时我们在A页面有涉及到mqq.invoke等方法的地方,能加上callback的,我们统一都加上测试代码,比如类似的代码,如果A页面有执行这个callback,我们可以从对应的ns和method入手查:

代码语言:javascript
复制
var img = new Image();
img.src = 'https://h5.qzone.qq.com/proxy/domain/www.qq.com/xxx/xxx';

结果上面的img的请求根本没发出来,而且我们在invokeClientMethod中设置的错误信息,只有openUrl的日志,这个是合理的,因为A打开B页面,A调用的就是openUrl,我们感觉有些没辙了。。。客户端没问题,H5也没问题,问题在哪?明明有jserror报错,而且也很怀疑是和事件监听有关,可是我们H5能做的比较有限;

(3)峰回路转:

在和xixin重现错误的时候,碰到一个常见的联调问题,就是js缓存,经常需要重新清理缓存,而且也可能代理不到本地,给重现带来一定的困扰;比如A打开B,如果A加上了_proxy=1走到了wns-html,可能都没有js请求,这样我们设置的什么代理都没用,清理缓存也不一定行。。。很焦急的看着时间慢慢流逝。。。没办法,只能先把url地址修改下,去掉_proxy=1,在聊天消息框中打开对应的url,总算可以代理上了,可以看到正常的invokeClientMethod的日志信息,意外出现了,在AIO聊天窗口打开的页面,居然没有报错???为什么?目前来看已有的信息,就是为什么从好友动态进入,一定会报错,而从QQ聊天点击链接进去就不会报错?都是同样打开的webview,H5的代码没变,那我们唯一可以确定的就是webview有什么差别;

只能继续求助于客户端,客户端保罗大神pauloliu根据这个线索,对比了代码,结果如下:

代码语言:javascript
复制
空间和AIO里面打开url,用的都是一个activity,但是确实aio里面打开的不会有问题。
AIO里面打开url的intent:
Bundle[{qqBrowserActivityCreateTime=1505354889492, fling_action_key=2, from_aio=1, param_force_internal_browser=false, friendUin=373922647, from_aio_opt=1, preAct=QQBrowserDelegationActivity, leftViewText=返回, aio_open_web=true, fling_code_key=199961721, fromAio=true, from_aio_time=43533567, uinType=0, articalChannelId=2, useDefBackText=true, startOpenPageTime=1505354885699, uin=2577199125, url=https://h5.qzone.qq.com/h5plus/home/index/alpha?_proxy=1&_wv=3&_nav_alpha=0&from=qqnavigation, preAct_time=1505354885699, key_isReadModeEnabled=true, needSkey=true, injectrecommend=true, curtype=0}]
空间的
Bundle[{qqBrowserActivityCreateTime=1505355030872, key_isFromQZone=true, fling_action_key=2, preAct=QQBrowserDelegationActivity, leftViewText=返回, fling_code_key=158123890, articalChannelId=5, startOpenPageTime=1505355027800, source_name=QQ空间, uin=2577199125, url=https://h5.qzone.qq.com/h5plus/home/index/alpha?_proxy=1&_wv=3&_nav_alpha=0&from=qqnavigation, fromQZone=true, preAct_time=1505355027800, key_isReadModeEnabled=true, needSkey=true, injectrecommend=true, insertPluginsArray=[Ljava.lang.String;@27f8d6b, isNeedAdvReport=false, post_data=null}]

我们都发现了下面多了一个insertPluginsArray,这个是干嘛的?insertPluginsArray代码如下:

在浏览器中插入了一个Qzone的命名空间,这个是啥?Qzone是个大插件,里面东西太多了,保罗发现干掉这个插件就OK了,那证明问题就出在这个Qzone插件上;找到源头我们也感觉有了一丝丝希望;在客户端同学努力下,问题根源找到了:

输入面板关闭的时候,会发出一个广播,而这个广播的接收者在webview初始化的时候就被创建了,所以每个web页面都可以收到。。。所以问题的原因我们来回归下:

我们从小游戏页面进入宠物页面,在宠物页面聊天的时候,会调用TopicComment这个方法,同时也会注册一个回调;关闭输入框会执行一下这个callback,方法名是上面的报错的哪个匿名方法,这个回调方法命名规则就是MQQ_CALLBACKAUTO+SN(这个SN的值UUIDSeed自增生成),在A页面因为没有注册这个回调方法,但是在A页面却收到了这个广播,这个是浏览器层面的事件监听,但是没有对应的回调方法,所以报错了,不过不影响功能,只是影响了jserror的统计;客户端同学也已经修复了这个bug,在下个版本会兼容处理;

通过这次的问题定位,对我们未来碰到类似的问题进行解决的时候,提供了思路,就是客户端可能会在浏览器加载的时候,不时的插入一些包括js,事件等等,如果没有相应的代码进行辅助证明,可以从这个角度去定位,举一反三下 :)

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档