1 |
|
很简单的页面,jquery.js 和 paper.js 加载完,然后调用 __Exam_PaperInit()
进行初始化。在办公室、家里都没出现过问题,但是在学校的机房里访问这个页面,时不时的出错,提示如 __Exam_PaperInit()
不存在,这么简单直接的逻辑,咋会出错呢,想不明白,猜测例如是不是机房的环境网络设置有问题等,但花了很久仍然找不到原因,更要命的是,系统过几天就有几千人要用来考试了,问题解决不了的话,可以想象影响会有多大。
多番查找资料,分析出错时的网络加载情况,发现了些奇怪的地方 (开始的时候都视而不见,因为看到了也不知道是啥):
发现如上图 paper.js 加载了 2 次,第一次加载的大小明显不对,第二次加载的时候大小对了,但还加上了个时间戳,我们的程序里没有加这个时间戳啊,哪里来的?还发现个奇怪的请求 /a
,我们的网页里没有发过这个请求,点开它一看,具体的 URL 是 http://124.232.160.178/v1/a,很奇怪的 IP,到网上一搜索,发现是运营商的广告拦截,这下拨云见日、豁然开朗了:
加载 jquery.js
加载 paper.js,但是它被运营商拦截,返回的内容逻辑如
1
2request('http://xxx.com/js/paper.js')
request('http://124.232.160.178/v1/a')发起异步加载 paper.js 和 /a
jquery.js 和
paper.js因为都加载完了,所以接下来执行__Exam_PaperInit()
初始化,结果出错,因为这时的 paper.js 不是真正的 paper.js,而是运营商劫持后返回来的,所以里面是不存在__Exam_PaperInit()
的异步加载 paper.js 完成,可以看到下面的
paper.js?_t1524016700292=0i
请求,它的 Initiator 是 paper.js (被劫持),这也就明白了为啥 paper.js 有 2 个请求当真正的 paper.js 加载完的时候已经晚了,因为初始化函数早就执行完了
问题终于弄清楚了,搞不定运营商,投诉没用啊,只能在代码和服务器上想办法了,有 2 个办法:
网站使用 HTTPS,这样就能防止被运营商劫持了,不用修改一点代码,但是升级到 HTTPS 需要申请证书、配置 Nginx 或者服务器,也不是一下会就能搞好的,不懂的人更是困难重重,不过这是最好的方案
循环检查、确保需要的对象
jQuery
和__Exam_PaperInit
都存在时才进行初始化:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html lang="en" dir="ltr">
<head>
<script src="/js/jquery.js" charset="utf-8"></script>
<script src="/js/paper.js" charset="utf-8"></script>
</head>
<body>
<script>
var intervalId = setInterval(function() {
if (typeof jQuery == 'undefined') { return; }
if (typeof __Exam_PaperInit == 'undefined') { return; }
clearInterval(intervalId);
__Exam_PaperInit();
}, 100);
</script>
</body>
</html>