有啊网页诊断工具相关总结

有啊网页诊断工具是一个轻量级的浏览器环境检测工具,基于Javascript以及Flash实现。它的主要功能包括问题检测以及针对某些问题给予提示性的建议,从而帮助用户自助的解决一些简单的问题。此外还能生成简单的检测报告,通过报告开发人员可是获得更为详细的环境信息,为解决问题提供有效的支持。

该工具具体的检测项包括以下几个:

1. Javascript版本信息
2. Cookie是否开启
3. 用户的屏幕分辨率
4. Flash版本号以及浏览器是否开启了Flash拦截功能
5. 浏览器字体大小是否正常(某些浏览器缩放后会导致页面布局混乱)
6. 浏览器的Ajax功能是否正常,包括Get方式和Post方式
7. 浏览器的图片浏览功能是否正常
8. 用户的网络速度

通过对以上几个问题的检测,开发人员能够比较全面的了解目标浏览器的整体环境。

 

一、Javascript版本检测

对于Javascript版本的检测似乎显得不是那么必要,因为通常都可以根据浏览器的版本找到对应关系,不过作为浏览器环境的一部分,还是把该功 能加了进来。具体的实现原理:在页面中嵌入各个版本的script标签,并在每个标签中都给同一个全局变量赋值,最后根据变量的值得到版本号:

     
 JS_VERSION=('1.0');    

     
 JS_VERSION=('1.1');    

     
 JS_VERSION=('1.2');    

      ......
      ......
     
 JS_VERSION=('1.3');    

     
 window.onload = function(){
 if( typeof JS_VERSION != 'undefined' )
 document.getElementById('test').innerHTML = JS_VERSION;
 }    
  

根据W3C规范,script的language属性已经被废弃了,不过经测试该属性的兼容性较好,并能得到比较准确的结果。如果使用type= “text/javascriptN”则在很多浏览器下得不到正确的版本,因此在此依然使用了language属性。另外,关于javascript各个版本与浏览器的对应关系可以参考如下表格:

 

Version Release date Equivalent to Netscape
Navigator
Mozilla
Firefox
Internet
Explorer
Opera Safari Google
Chrome
1.0 March 1996   2.0   3.0      
1.1 August 1996   3.0          
1.2 June 1997   4.0-4.05          
1.3 October 1998 ECMA-262 1st edition / ECMA-262 2nd edition 4.06-4.7x   4.0      
1.4     Netscape
Server
         
1.5 November 2000 ECMA-262 3rd edition 6.0 1.0 5.5 (JScript 5.5),
6 (JScript 5.6),
7 (JScript 5.7),
8 (JScript 6)
6.0,
7.0,
8.0,
9.0,
10.0
   
1.6 November 2005 1.5 + Array extras + Array and String generics + E4X   1.5     3.0, 3.1  
1.7 October 2006 1.6 + Pythonic generators + Iterators + let   2.0     3.2, 4.0 1.0
1.8 June 2008 1.7 + Generator expressions + Expression closures   3.0        
1.8.1   1.8 + Native JSON support + Minor Updates   3.5        
1.8.2   1.8.1 + Minor updates   3.6        
1.9   1.8.1 + ECMAScript 5 Compliance   4        

 


 

相关参考资料:

http://www.w3.org/TR/REC-html40/interact/scripts.html W3C 关于script标签的描述

http://en.wikipedia.org/wiki/JavaScript#Versions *关于JavaScript中的版本描述

https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/JavaScript_Overview JavaScript Versions and ECMAScript Editions

http://hi.baidu.com/jiaozhenqing/blog/item/d8f026380392f22cb9998fc7.html JavaScript版本一览

二、检测Cookie是否开启

先获取window.navigator['cookieEnabled']的值,如果该值非undefined的话则直接使用该值即可判断(经测 试IE7、Firefox3.5、Safari4、Opera10均能支持)。如果为undefined(即不支持该属性)则使用如下的方式:尝试向 Cookie中写入数据(为避免浪费设置1分钟的有效期),写入后检测document.cookie中是否存在刚才写入的数据,如果有则cookie有 效否则cookie无效:


  1. var cookie = document.cookie;  
  2. var cookieEnabled = window.navigator['cookieEnabled'];  
  3.  
  4. if(typeof cookieEnabled == 'undefined'){  
  5.    var expireDate = new Date();  
  6.    expireDate.setTime(expireDate.getTime() + 1000);//Expired after 1 second  
  7.    var time = expireDate*1;  
  8.    var regExp = new RegExp(time + '=' + time);  
  9.    document.cookie = time + '=' + time + ';expires=' + expireDate.toGMTString();  
  10.    if( regExp.test(document.cookie) )  
  11.       cookieEnabled = true;  
  12.    else  
  13.       cookieEnabled = false;  
  14. }  

三、Flash版本以及可用性检测

Flash检测包含两方面的内容:

1. Flash是否安装、禁用,Flash版本号

对于Flash的版本检测可以通过在页面中引入AC_OETags.js(包含在Adobe官方的Flash Player Detection Kit中),然后通过调用其中的GetSwfVer方法获得具体的版本号,如果Flash未安装或者被禁用则 GetSwfVer方法将会返回-1,否则返回正确的版本号。查看GetSwfVer的实现,与浏览器版本检测如出一辙,也是通过navigator信息 得到的,感兴趣的可以直接查看其源码。

2. 如果Flash已经安装是否被拦截

做这一步检查的前提是第一步能够获得正确的版本号。具体的检测方法也很简单,在页面中引入一个自定义的swf文件,在该swf文件中只定义 了一个方法checkFlash,并将该方法暴露出来使得JavaScript能够访问到,即 ExternalInterface.addCallback(“checkFlash”,checkFlash);在swf加载完成后通过JavaScript访问checkFlash方法,如 果存在该方法则说明Flash访问正常,否则Flash可能被拦截了。

以上两步的代码实现大致如下:

HTML代码

 

Javascript代码


  1. //获取Flash版本号,如果version为-1则可能未安装Flash或者Flash被禁用  
  2. var version = GetSwfVer();  
  3. if( version != -1 ){  
  4.      var isIE = navigator.appVersion.indexOf("MSIE") != -1;  
  5.      if( isIE )//IE下取Object元素  
  6.         var swfObj = document.getElementById('oCheck');  
  7.     else//其他浏览器下取embed元素  
  8.         var swfObj = document.getElementById('eCheck');  
  9.     if( !swfObj.checkFlash ) {  
  10.         //被拦截  
  11.     }  
  12.     else {  
  13.        //未拦截  
  14.     }  
  15. }  
  16. else{  
  17.     //未安装Flash Player或者Flash Player被禁用  
参考资料


 

四、Ajax功能检测

该功能的检测比较直接,即分别构造Ajax Get和Ajax Post请求,在请求过程中详细的记录Ajax的实例类型(ActiveXObject 或 XMLHTTPRequest)、请求的各个阶段的状态以及最终的请求结果。

五、检测图片是否被禁用

检测图片是否禁用的原理:新建一个Image对象,并监听其 事件)以及onerror事件。


  1. var img = new Image;  
  2. //监听 imgimg.onload = img.onreadystatechange = function(){  
  3. //加载成功说明图片功能是正常的  
  4. }  
  5. //监听onerr事件  
  6. img.onerror = function(){  
  7. //如果触发了onerror事件,则说明图片功能不正常(在img的src正确的情况下)  
  8. }  
  9. img.src = 'xxx'

以上的实现中,对于加载事件的监听并没有什么问题,不过对于onerror事件还是存在比较大的兼容性问题:经测试发现,在IE下禁用图片后并不会触发 onerror事件,而在Firefox中禁用图片后则能正常的触发onerror事件,至此的结论是使用onerror来判断图片功能是准确的。取而代 之的是使用超时检测来判断,即假定图片在一定时间内仍未能加载成功则视为失败。


  1. var img = new Image;  
  2. //监听 imgimg.onload = img.onreadystatechange = function(){  
  3. //加载成功说明图片功能是正常的  
  4. }  
  5. //监听onerr事件  
  6. img.onerror = function(){  
  7. //如果触发了onerror事件,则说明图片功能不正常(在img的src正确的情况下)  
  8. }  
  9. img.src = 'xxx';  
  10. var timer = setTimeout(function(){  
  11. //如果执行到这里则认为图片功能异常  
  12. },TIMEOUT); 

六、检测网络速度

实现原理:请求一张已知大小的图片N次,并分别记录每次请求所花费的时间,最后根据图片大小计算出平均的网络速度。这里需要注意的是图片的大小问题,图片如果太小结果会不准确,需要选择一张合适的图片,另外为防止图片被浏览器缓存需要给图片的src添加时间戳。


  1. /*  
  2.  * @param { Integer } times 请求图片的次数  
  3.  * @callback { Function } callback 图片请求完成后调用的函数  
  4.  */  
  5.  function detectNetSpeedWithImage(times,callback){      
  6.  timestimes = times || 1;  
  7.  //已完成请求  
  8.  var completedImg = 0,  
  9.  res = [],  
  10.  timer = null,  
  11.  done = false;          
  12.  for( var i = 0; i < times; i++){  
  13.  (function( index ){  
  14.  setTimeout(function(){              
  15.  var img = new Image();  
  16.  //开关,在某些浏览器(如IE)会响应两次onreadystatechange  
  17.  var loaded = false;  
  18.  //请求开始时间  
  19.  var tStart = new Date();  
  20.  imgimg.onload = img.onreadystatechange = function(){  
  21.  if( loaded ) return;  
  22.  //请求结束时间  
  23.  var tEnd = new Date();  
  24.  res.push(tEnd - tStart);  
  25.  //已完成请求加1  
  26.  completedImg++;  
  27.  loaded = true;  
  28.  //全部请求完成后调用callback  
  29.  if( completedImg == times && callback ){  
  30.  callback.call(null,res);  
  31.  if( timer ) clearTimeout(timer);  
  32.  }  
  33.  }  
  34.  img.onerror = function(){  
  35.  if( done ) return;  
  36.  callback([]);  
  37.  done = true;  
  38.  clearTimeout(timer);  
  39.  }  
  40.  img.src = Config.NET_SPEED_DETECT_IMAGE_URL + '?t=' + (new Date())*1;  
  41.  },index * Config.NET_SPEED_DETECT_IMAGE_REQUEST_INTERVAL);  
  42.  })(i);  
  43.  }  
  44.  //超时操作  
  45.  timer = setTimeout(function(){  
  46.  if( completedImg != times && !done ){  
  47.  callback([]);  
  48.  }  
  49.  },Config.NET_SPEED_DETECT_TIMEOUT + times * Config.NET_SPEED_DETECT_IMAGE_REQUEST_INTERVAL);  
  50.  }  
  51.  
  52.  detectNetSpeedWithImage(Config.NET_SPEED_DETECT_TIMES,function(res){  
  53.  //失败  
  54.  if( res.length < 1 ){  
  55.  _handleError();  
  56.  }  
  57.  //成功  
  58.  else{  
  59.  var time = 0;  
  60.  for( var i = 0,l = res.length; i < l; i++){  
  61.  time += res[i] / ( l * 1000 );  
  62.  }  
  63.  //计算速度  
  64.  var speed = Config.NET_SPEED_DETECT_IMAGE_SIZE / time;  
  65.  //取小数点后两位  
  66.  speedspeed = speed.toFixed(2);          
  67.  me.isOver = true;      
  68.  }  
  69.  }); 

七、检测客户端分辨率

直接获取window.screen的width与height即可。

八、检测浏览器字体大小是否正常

在IE6下,当使用px作为单位时,元素(字体大小)无法进行缩放,这在很多情况下都会造成页面混乱。另外,对于目前大多数浏览器,在默认字体设置下,1em恰恰等于16px,于是可以根据这个原理来检测浏览器字体是否正常,具体的方式如下:

1. 创建一个DIV元素1,并设定其高为16px,宽为1px并使用CSS将其定位到可视范围之外(不能通过display或visibility隐藏)

2. 创建另一个DIV元素2,并设置其font-size为medium。在该DIV内部创建一个DIV元素3,并设置其高位1em,宽为1px并使用CSS将其定位到可视范围之外

3. 比较元素1和元素3的高度,如果相等则字体大小正常否则异常

注意,元素3必须包含在元素2中,并且给元素2设置font-size: medium。因为em是一个相对单位,1em的大小相当于其父元素字体的大小,为了使检测不受其他样式影响,将其放在一个字体大小为浏览器默认值的容器中。


  1. //隐藏DIV的CSS  
  2. var hideCSS = 'position:absolute;left:-2000px;';  
  3.  
  4. //以px为宽度单位的元素  
  5. var pxBlock = document.createElement('div');  
  6. pxBlock.style.cssText = 'width:16px;height:1px;' + hideCSS;  
  7. document.body.appendChild(pxBlock);  
  8. //构建一个字体大小为浏览器默认值的容器  
  9. var emBlockWrapper = document.createElement('div');  
  10. emBlockWrapper.style.fontSize = 'medium';  
  11.  
  12. //以em为字宽度单位的元素  
  13. var emBlock = document.createElement('div');  
  14. emBlock.style.cssText = 'width:1em;height:1px;' + hideCSS;  
  15.  
  16. emBlockWrapper.appendChild(emBlock);  
  17. document.body.appendChild(emBlockWrapper);  
  18.  
  19. //获得固定和变化的div宽度  
  20. var pxBlockpxBlockWidth = pxBlock.offsetWidth;  
  21. var emBlockemBlockWidth = emBlock.offsetWidth;  
  22.  
  23. if(pxBlockWidth == emBlockWidth){  
  24. //字体正常  
  25. }  
  26. else{  
  27. //字体异常  

 












本文转自百度技术51CTO博客,原文链接:http://blog.51cto.com/baidutech/746992,如需转载请自行联系原作者
上一篇:流程控制语句:if语句 | Python从入门到精通:入门篇之十一


下一篇:Windows系统如何使用阿里云文件存储