记一次 JS 偶发性加载失败的经历

什么么么么

问题描述

前段时间,偶尔会有同事反映某页面会崩溃。几率极低,且毫无规律!
我自己尝试了一下,果然!没有任何问题!
问题无法重现,也就没当回事。

直到有一天,我在测试时,也遇到了页面崩溃的情况。

图1

页面是用 vue 实现的,崩溃后,vue 模板代码全部暴露出来了!
奇怪的是,刷新一下,页面就会恢复正常。

图2

真让人头疼。

问题定位

一开始,不会用PC调试移动端页面(本人并没有开发移动端的经验),后来查了一下相关资料,使用 USB+Chrome 就可以在 PC 上调试移动端(Android)的页面了。
这样问题就简单了。

首先,打开该页面,看一下具体的异常输出,如图:

图3

调试时,发现 chrome 中,network 部分,我请求的 axios+vue 文件,反馈回来的并非是预料内的内容,而是一堆其他代码:

图4

提取出来,并格式化后:

图5

根据这段代码,我明白了为什么会有 图 3 中的异常:Uncaught TypeError: Cannot read property 'appendChild' of undefined

首先,我的 axios + vue 文件的 script 是放在 head 标签内的,浏览器加载这个标签的时候,还没有构造出 body 元素!但尴尬点在于,这两个文件被注入后,反馈回来的js脚本内容中有这么一句立即执行的代码 document.getElementsByTagName('body')[0].appendChild(l),既然没有 body 元素,又怎么可能 append 成功呢!

查明真相

为了搞明白,这个鬼东西到底想注入什么内容,我决定把 <script src="/assets/js/axios.min.js"></script><script src="/assets/js/vue.min.js"></script> 写到 body 里,让这个鬼东西如愿以偿。

修改后的效果如图:

修改后的页面

此时,页面已经不会报错了,调试发现,注入进来的脚本在页面内添加了蓝色箭头所指的两个 script 标签,并且注入了一个 iframe(红框内的内容)。
至此,真相大白!

解决方案

我所使用的解决方案就是把我们的 http 链接换成 https

其他疑惑

虽然知道了是“被注入”引起的问题,但目前还没能确定注入源。只是网上查了一下注入内容中的“站长统计”。但不清楚这个流氓东西是怎么做到的。
特此,望知情者能帮助解答,感激不尽!

阅读 3.9k

383 声望
4 粉丝
0 条评论
383 声望
4 粉丝
文章目录
宣传栏