• 作者:老汪软件技巧
  • 发表时间:2024-09-07 15:05
  • 浏览量:

发生什么事了

某天,我正在愉快的摸鱼,然后我看到测试给我发了条消息,说我们这个系统在UC浏览器中有问题,没办法操作,点了经常没反应(测试用得iPhone14,是一个h5的项目)。我直接懵了,这不是都测了好久了吗,虽然不是在uc上测得,chrome、safari、自带浏览器等,都没这个问题,代码应该是没问题的,uc上为啥会没有反应呢?难道是有什么隐藏的bug,需要一定的操作顺序才能触发?我就去找了测试,让他重新操作一下,看看是啥样的没反应。结果就是,正常进入列表页(首页),正常点某一项,正常进入详情页,然后点左上角返回,没反应。我上手试了下,确实,打开vconsole看了下,也没有报错。在uc上看起来还是必现的,我都麻了,这能是啥引起的啊。

找问题

在其他浏览器上都是好好的,uc上也不报错,完全看不出来代码有啥bug,完全没有头绪啊!那怎么办,刷新看看:遇事不决,先刷新,还不行就清空缓存刷新。刷新了之后,哎,好了!虽然不知道是什么问题,但现在已经好了,就当作遇到了灵异事件,我就去做其他事了。

过了一会,测试来找我了,说又出现了,不止是详情页,进其他页面也返回不了。这就难受住了呀,说明肯定是有问题的,只是还没找到原因。我就只好打开vconsole,一遍一遍的进入详情页点返回;刷新再进;清掉缓存,再进。

然后,我就发现,network中,出现了一个没有见过的请求

根据track、collect这些单词来判断,这应该是uc在跟踪、记录某些操作,requestType还是个ping;我就在想,难道是这个请求的问题?但是请求为啥会导致,我页面跳转产生问题?然后我又看到了intercept(拦截)、pushState(history添加记录),拦截了pushState?

这个项目确实使用的是history路由,问题也确实出在路由跳转的时候;而且出现问题的时候,路由跳转,浏览器地址栏中的地址是没有变化的,返回就g了(看起来是后退没有反应,实际是前进时G了)。这样看,uc确实拦截了pushState的操作。那它是咋做到的?

原来如此

浏览器有毒_浏览器下载有病毒怎么办_

然后,我想起来,前段时间在掘金上看到了一篇,讲某些第三方cdn投毒的事情,那么uc是不是在我们不知情的情况下,改了我们的代码。然后我切到了vconsole的element,展开head,发现了一个不属于我们项目的script,外链引入了一段js,就挂在head的最顶上。通过阅读,发现它在window的history上加了点料,覆写了forward和pushState(forward和pushState是继承来的方法)

正常的history应该是这样:

复写的类似这样:

当然,有些系统或框架,为了实现某些功能,比如实现触发popstate的效果,也会复写

但uc是纯纯的为了记录你的操作,它这玩意主要还有bug,会导致路由跳转出问题,真是闹麻了

如何做

删掉就好了,只要删掉uc添加的,当我们调用相关方法时,history就会去继承里找

// 判断是否是uc浏览器
if (navigator.userAgent.indexOf('UCBrowser') > -1) {
    if (history.hasOwnProperty('pushState')) {
        delete window.history.forward
        delete window.history.pushState
    }
    // 找到注入的script
    const ucScript = document.querySelector('script[src*="ucbrowser_script"]')
    if (ucScript) {
        document.head.removeChild(ucScript)}
    }
}

吐槽

你说你一个搞浏览器的,就不能在底层去记录用户行为吗,还不容易被发现。主要是你这玩意它有bug呀,这不是更容易被发现吗。(这是23年11月份遇到的问题,当时产品要求在qq/百度/uc这些浏览器上也都测一下才发现的,现在记录一下,希望能帮助到其他同学)