镜像站点简易测速

Author: 周辉腾 Date: 2000年 第31期

  在给自己的网站建立多个镜像站点之后,最让我们头疼的是如何实时地选择并确定一个连接速度最快的镜像,难道还要使用“ping”大法吗?理论上是可行的,但是这工作量也太大了吧?别急,简单易用的JavaScript在这里是能帮上一点小忙的……
  我们知道,如果浏览器试图下载一个不存在或者说是来自错误地址的图像,服务器会返回给浏览器一个错误信息,然后由浏览器直观地告诉你当前地址的图像不存在,这就是HTML文档的图像载入错误事件。请看以下例子:(^31040202a^)
  <!将以下代码插在<body>……</body>标签之间,下同 >
  <img src=″http://ctsight.topcool.net/test.gif″ width=″1 ″height=″1″ onerror=″window.alert(′图像载入错误′)″>
  在本例中因为这个URL的图像是不存在的,所以等服务器响应之后便会触发onerror事件并执行已定义好的函数。既然这个事件可以让服务器返回信息,那么……想到了吗?返回的错误信息虽然没什么用,但是由此我们可以定性地判断服务器的响应速度。
  问题似乎明朗了,但是怎样获取这个“服务器响应的时间"呢?只要让你可爱的浏览器去下载目标服务器上的一个不存在的图像并开始计时,等服务器告诉浏览器说你要下载的图片不存在即本图像的“onerror"事件发生时候你停止计时并把所花费的时间写出来,哈哈,大功告成也!请看下例:
  <script language=″JavaScript″><!--
  var intTime=0;
  setInterval(″intTime++″,10);
  document.write(′<img src=″ http://ctsight.topcool.net/test.gif″ width=″1″height=″1″ onerror=″window.alert(′当前连接时间是′+intTime/100+′秒′)″>′);
  //--></script>
  按照这个原理,如果不考虑其它情况,我们只要让浏览器同时下载你的不同镜像上的这种不存在的图像,等它们的“onerror”事件一一发生之后就可以很容易比较不同镜像的连接速度了!这看来是很激动人心的,但是,还有两个问题需要解决:第一,因为浏览器(包含IE和Netscape等主流浏览器)对HTML文档及其附属资料(如图像等)的下载是单线程从前往后的,就是说HTML源代码中写在前面的图片它会先下载,如果计时同时开始的话,那这样对写在后面的镜像就不公平。要避免这种弊端,就要用前一个图像“下载完”再下载下一个图像的方法,并对每个图片分开计时。第二,因为你的访客浏览器的缓存设置可能是“不检查”即不去检查上次访问过的文档(包括图像)是否更新,所以在这种情况下
    如果使用固定的图像,浏览器就直接使用上次的下载状态,这样会干扰第二次测试结果,甚至令测试结果跟实际情况大相径庭!所以要达到目的必须让浏览器自动下载那种我们称之为不会重复的并且不可能存在的图像。在这里我们用的是JavaScript的伪随机数即Math.random()作为“这种”图像的文件名,因为它的取值是跟时间有关系的,所以一般情况下能够达到目的。
  好了,到这里测试脚本的原理就算讲完了,下面给出的是较为简单的测试代码:
  <!把以下代码插在<head>……</head>标签之间 >
  <script language=″JavaScript″><!--
  var intCount=intTime=0;
  /* 在下面的数组中定义你的镜像站 */
  var mirrorUrl=new initArray(′www.yesky.com′,′dailynews.sina.com.cn′,′www.ohfilm.com′);
  function initArray(){
   this.length=initArray.arguments.length;
   for(var i=0;i<this.length;i++) this[i]=initArray.arguments[i];
  }
  function listTime(){
   var strInfo=′服务器′+mirrorUrl[intCount]+′的连接情况是:\n)′;
   if(intTime>=300) strInfo+=′服务器在30秒内没有响应′;
   else strInfo+=′连接时间′+intTime/10+′秒;
   window.alert(strInfo);
  }
  function changImg(){
   if(intCount<mirrorUrl.length) document.testImg.src=′ http://′+mirrorUrl[intCount]+′/′+Math.random()+′.gif′;
  }
  function goNext(){
   listTime();intCount++;intTime=0;changImg();
  }
  //></script>
  <!用以下这行代码修改原来的<body>标签 >
  <body onload=″window.setInterval(′intTime++′,100);changImg()″>
  <! 将以下代码插在<body>……</body>标签之间,代码中用src指定的图像URL必须是有效的,否则脚本将不能正常工作,在IE中可以省略整个src属性>
  <imgname=″testImg″src=″http://ctsight.topcool.net /logo.gif″width=″1″height=″1″ border=″0″onerror=″goNext()″>
  如果想较好地测试多个镜像使用的代码,要比上面讲述的麻烦一些,限于版面只能这样简化了,如果你想要获取详细的测试文档及源代码,请访问以下链接:http://ctsight.topcool.net/document/test_timeout.html,或来信与我交流:contion@21cn.com。