• ajax连接池和XMLHttpRequest


    连接池

    我们公司在路由和交换机web界面和后端交互全部采用的是自己封装的ajax组件完成的,组件有点老了,代码风格和其中的某些用法现在看起来都有点不习惯。今天把这个组件的核心部分的ajax连接池记录下来,如果以后有机会,就重新封装一个。

    先看看连接池的代码:

     1 var __XmlHttpPool__ ={
     2     m_MaxPoolLength: 10,
     3     m_XmlHttpPool: [],
     4     __requestObject: function () {
     5         var xmlhttp = null;
     6         var pool = this.m_XmlHttpPool;
     7 
     8         for (var i = 0; i < pool.length; ++i) {
     9             if (pool[i].readyState == 4 || pool[i].readyState == 0) {
    10                 xmlhttp = pool[i];
    11                 break;
    12             }
    13         }
    14 
    15         if (xmlhttp == null) {
    16             return this.__extendPool();
    17         }
    18 
    19         return xmlhttp;
    20     },
    21     __extendPool: function () {
    22         var xmlhttp = null;
    23         xmlhttp = __getXmlhttp(xmlhttp);  //创建新的XHR对象。
    24 
    25         if ((xmlhttp) && (this.m_XmlHttpPool.length < this.m_MaxPoolLength)) {
    26             this.m_XmlHttpPool.push(xmlhttp);
    27         }
    28         return xmlhttp;
    29     }41 };

    第9行中通过判断XMLHttpRequest对象的readyState值来获取可以使用的XMLHttpRequest对象(0代表open尚未使用,4代表响应完成),15行则是如果连接池中没有可用的XHR对象,则创建一个新的,并将新的XHR对象放入连接池。由于XHR对象在连接时会消耗资源,如果同时进行的ajax请求的太多会导致页面卡顿甚至浏览器出现未响应情况。所以一般不会同时使用太多的ajax请求。

    XMLHttpRequst:

    XMLHttpRequest的每个实例都表示一个独立的请求/响应对。由于兼容性问题,一般这样创建XHR对象。

        try {
            xmlhttp = new XMLHttpRequest();
        } catch (e) {
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
    

     在创建XHR对象后,发起HTTP请求的下一步是调用该对象的open()方法去指定请求的方法和URL。请求的方法一般为post和get,但是DELETE,HEAD,OPTIONS,PUT也是规范中允许的。其中HEAD在很多浏览器上已经得到支持。但是我对关于HEAD等这些方法的使用代码见的不多,仅仅在《javascript权威指南第六版》的例18-13中见到使用HEAD来实现ajax的跨域。OPEN的第二个参数UEL是请求的主题。这是相对于文档的URL,这个文档包含调用open()的脚步,如果指定绝对URL,协议,主机和端口通常必须匹配所在文档的对于内容:跨域的请求通常会报错。(但是当服务器明确允许跨域请求时,即在服务器响应时会发送合适的CORS,2级XMLHttpRequest规范会允许它。)

     header('Access-Control-Allow-Origin: http://arunranga.com');

    在使用XHR发起http请求时还可以设置请求头,例如POST请求需要"Content-Type"头指定请求主题的MIME类型。对于相同的头调用setRequestHeader()多次,新值不会取代之前指定的值,相反,HTTP请求将包含这个头的多个副本或这个头将指定多个值。由于XMLHttpRequest对象会自动处理cookie、连接时间、字符集和编码判断,所有无法改变Content-Length,Date,Referer,User-Agent,Accept-Charset,keep-Alive,User-Agent,Cookie,Host等。可以指定"Authorization"头,但是通常不用这样做,如果请求一个受到密码保护的URL,可以把用户名和密码作为open()的第四个和第五个参数,则XMLHttpRequest将设置合适的头。open的第三个参数是表示处理HTTP响应是同步还是异步。false表示同步,true表示异步。应当尽量避免使用同步,因为客户端javascript是单线程的,当send()方法阻塞时,它通常会导致整个浏览器UI冻结。当然使用Web Worker除外。

    在使用XHR发起HTTP请求的最后一步是指定可选的请求主体并使用send向服务器发送它。GET请求绝对没有主体,使用xmlhttp.sent(null)或直接xmlhttp.send()。POST请求通常拥有主体,同时它应该匹配使用setRequestHeader()指定"Content-Type"头。

    • status和statusText属性以数字和文本的形式返回HTTP状态码。
    • 使用getResponseHeader和getAllResponseHeaders()能查询响应头。XMLHttpRequest会自动处理cookie:它会从getAllResponseHeaders返回的集合中过滤掉cookie。

    为了在响应准备就绪是得到通知,必须监听XMLHttpRequest对象上的readstatechange事件。该事件会获得readyState属性

      0  : open()尚未调用

      1  : open()已调用

      2  : 接收到头信息

      3  : 接收到响应主体

      4  :  响应完成

    XMLHttpRequst 2:

    XHR2有监控HTTP请求上传的事件。在实现这些特性的浏览器中,XMLHttpRequest对象将有upload属性。upload属性值是一个对象,它定义了addEventListener()方法和整个progress事件集合,

    比如onproress和onload。注意,upload对象没有定义onreadystatechange属性,upload仅能触发新的事件类型。对于XHR对象xmlhttp,可以设置xmlhttp.onprogress以监控响应的下载进度,并设置xmlhttp.upload.onprogress以监控请求的上传进度。关于upload的使用,可以看如下代码:

    1 var xmlhttp = new XMLHttpRequest();
    2 xmlhttp.open("POST",url);
    3 xmlhttp.upload.progress = function(e){
    4   if(e.lengthComputable){
    5     console.log(Math.round(e.loaded/e.total*100) + "% Complete");
    6   }        
    7 }

     XHR增加了timeout属性,可以设置HTTP请求的时限。

     xmlhttp.timeout = 3000;

    XMLHttpRequest对象,不仅可以发送文本信息,还可以上传文件。

    假定files是一个"选择文件"的表单元素(input[type="file"]),我们将它装入FormData对象。

     var formData = new FormData();
      for (var i = 0; i < files.length;i++) {
       formData.append('files[]', files[i]);
     }
    
    //...
    
      xmlhttp.send(formData);

    从服务器取回二进制数据,较新的方法是使用新增的responseType属性。

    如果服务器返回文本数据,这个属性的值是"TEXT",这是默认值。较新的浏览器还支持其他值,也就是说,可以接收其他格式的数据。

    你可以把responseType设为blob,表示服务器传回的是二进制对象。

     1 var xmlhttp = new XMLHttpRequest(); 2   xmlhttp.open('GET', '/path/to/image.png'); 3   xmlhttp.responseType = 'blob'; 

    接收数据的时候,用浏览器自带的Blob对象即可。

     1 var blob = new Blob([xhr.response], {type: 'image/png'}); 

    参考资料:

    XMLHttpRequest Level 2 使用指南

    《javascript权威指南》

  • 相关阅读:
    JAVA设计模式之策略模式
    Outlook邮箱配置
    Linux命令
    开发工具使用技巧
    java连接VMware虚拟机Oracle数据库问题
    C#创建带有界面交互的windows服务
    Google Galaxy Nexus刷系统
    业务逻辑?到底是什么
    发明轮子
    IBM服务器机组初始设置
  • 原文地址:https://www.cnblogs.com/towersxu/p/4372439.html
Copyright © 2020-2023  润新知