2019独角兽企业重金招聘Python工程师标准>>>

 

在ajax应用中,通常一个页面要同时发送多个请 求,如果只有一个XMLHttpRequest对象,前面的请求还未完成,后面的就会把前面的覆盖掉,如果每次都创建一个新的 XMLHttpRequest对象,也会造成浪费。解决的办法就是创建一个XMLHttpRequset的对象池,如果池里有空闲的对象,则使用此对象, 否则将创建一个新的对象。

下面是我最近写的一个简单的类:

/**
 * XMLHttpRequest Object Pool
 *
 * @author    legend <legendsky@hotmail.com>
 * @link      http://www.ugia.cn/?p=85
 * @Copyright www.ugia.cn
 */

var XMLHttp = {
    _objPool: [],

_getInstance: function ()
    {
        for (var i = 0; i < this._objPool.length; i ++)
        {
            if (this._objPool[i].readyState == 0 || this._objPool[i].readyState == 4)
            {
                return this._objPool[i];
            }
        }

// IE5中不支持push方法
        this._objPool[this._objPool.length] = this._createObj();

return this._objPool[this._objPool.length - 1];
    },

_createObj: function ()
    {
        if (window.XMLHttpRequest)
        {
            var objXMLHttp = new XMLHttpRequest();

}
        else
        {
            var MSXML = ['MSXML2.XMLHTTP.5.0', 'MSXML2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP'];
            for(var n = 0; n < MSXML.length; n ++)
            {
                try
                {
                    var objXMLHttp = new ActiveXObject(MSXML[n]);
                    break;
                }
                catch(e)
                {
                }
            }
         }

// mozilla某些版本没有readyState属性
        if (objXMLHttp.readyState == null)
        {
            objXMLHttp.readyState = 0;

objXMLHttp.addEventListener("load", function ()
                {
                    objXMLHttp.readyState = 4;

if (typeof objXMLHttp.onreadystatechange == "function")
                    {
                        objXMLHttp.onreadystatechange();
                    }
                },  false);
        }

return objXMLHttp;
    },

// 发送请求(方法[post,get], 地址, 数据, 回调函数)
    sendReq: function (method, url, data, callback)
    {
        var objXMLHttp = this._getInstance();

with(objXMLHttp)
        {
            try
            {
                // 加随机数防止缓存
                if (url.indexOf("?") > 0)
                {
                    url += "&randnum=" + Math.random();
                }
                else
                {
                    url += "?randnum=" + Math.random();
                }

open(method, url, true);

// 设定请求编码方式
                setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
                send(data);
                onreadystatechange = function ()
                {
                    if (objXMLHttp.readyState == 4 && (objXMLHttp.status == 200 || objXMLHttp.status == 304))
                    {
                        callback(objXMLHttp);
                    }
                }
            }
            catch(e)
            {
                alert(e);
            }
        }
    }
};

示例:

<script type="text/javascript" src="xmlhttp.js"></script>
<script type="text/javascript">
function test(obj)
{
    alert(obj.statusText);
}

XMLHttp.sendReq('GET', 'http://www.ugia.cn/wp-data/test.htm', '', test);
XMLHttp.sendReq('GET', 'http://www.ugia.cn/wp-data/test.htm', '', test);
XMLHttp.sendReq('GET', 'http://www.ugia.cn/wp-data/test.htm', '', test);
XMLHttp.sendReq('GET', 'http://www.ugia.cn/wp-data/test.htm', '', test);

alert('Pool length:' + XMLHttp._objPool.length);
</script>

demo 下载xmlhttp.js

Permalink

50 Comments &raquo;

  1. s5s5 said,

    December 22, 2005 @ 7:12 pm

    大哥哥,你的日志时间超前了吧,已经在BXNA显示了一天了。。。

  2. legend said,

    December 22, 2005 @ 7:19 pm

    我发现这个问题了,后台的时间选项改了改,没管用,帖子时间我也改了。郁闷

    再改,改到21号

  3. danielking said,

    December 23, 2005 @ 9:12 am

    怎么在IE下使用有问题呢?
    提示64行第5个字符,缺少标识符字符串或数字
    然后提示XMLHttp未定义

    在Firefox使用正常

  4. legend said,

    December 23, 2005 @ 9:39 am

    源代码里有中文的注释,是ansi的,如果你的网站或ie下选择编码为UTF-8,可能会导致错误,你把你ie的编码改成gb2312看看,或者去掉文件里的中文注释

  5. nickfan said,

    December 26, 2005 @ 10:48 am

    服务器是不是php5的?可能需要设置一下php.ini。

  6. andot said,

    December 27, 2005 @ 5:28 pm

    测试自动转向

  7. legend said,

    December 27, 2005 @ 5:31 pm

    测试自动转向

  8. andot said,

    December 27, 2005 @ 8:12 pm

    测试自动跳转

  9. 野马 said,

    December 29, 2005 @ 3:57 pm

    思路非常好,小弟在下提几个建议:
    1、“对象池”的管理功能需要加强,比如池的容量。
    2、“对象池”的内存回收需要加强,比如使用完毕的对象释放内存。
    3、请求最好序列一下,以控制由于服务器延时或网络延时导致的先请求的后得到结果。
    4、为了代码复用和健壮,回调函数应该验证是否有效,也就是回调函数应该可以为空(可以缺省)。

  10. legend said,

    December 31, 2005 @ 9:57 am

    谢谢“野马”的建议,有空再完善一下。IE默认有两个线程的限制,所以池的容量不需要很大。

  11. hzy said,

    December 31, 2005 @ 1:11 pm

    看 了legend的代码,才知道啥叫高手。很想请教legend,这些mozilla和ie各自特性和差别的资料从何处得来?因为我花了2个多钟头才查到 push和pop是ie5.5以后才有的;javascript中对象的构造O={:,:,:…}是javascript1.2里面就有的(因此这样写而 不是用new object()或者function objectname(){}应该具有更好的兼容性);以及那个很有意思的addeventlistener是mozilla的DOM里面特有的。查到这 些东东,我的文件夹里面已经堆满了dom,javascript的相关规范了,而且还是E文的,这多少让我有些灰心。还有几个问题,那个load是不是 mozilla里面xmlhttprequest的事件?load对应readystate=4,那么还有没有0,1,2,3对应的其他事件?因为我在 www.xmlhttp.cn上面没有找到这个信息,xmlhttprequest我在mozilla的DOM文档里面也没有找到。另外,那个“IE默认 有两个线程的限制,所以池的容量不需要很大”这句不太明白。
    感谢你的这些文章和代码,如果能够解答我的这些疑问的话,就更感谢了,呵呵。
    敬佩!

  12. hzy said,

    December 31, 2005 @ 2:09 pm

    PS, “Content-Type=application/x-www-form-urlencoded; charset=UTF-8″是给服务器看的,xmlhttprequest并不会因此去编码data中的数据,因此data被send之前,需要手工编 码。我在IE下面用post试了一下,自己构造了一个form表单在http请求中的形式name1=value1&name2=value2, 如果不事先编码的话,value中如果有“?”或者汉字之类的字符,就会导致出错。对于get也有类似的问题。IE下面有encodeURI等几个函数用 来对字符串编码,可以解决这个问题,但这需要浏览器版本IE5.5以上(尽管encodeURI系列是ECMAScript标准)。我找到了一个可以进行 url编码的脚本,但仅仅是那个unicode和gb2312的对应数组,就一百多K。
    想请教legend,是否有比较好的通用的解决方法?谢谢。

  13. legend said,

    December 31, 2005 @ 2:52 pm

    回 答hzy:一些浏览器方面的差别是我在以前做东西的时候遇到的,所以后面写代码的时候可以去避免这些问题。addeventlistener这个是参考 webfx上的一些代码。至于mozilla中xmlhttprequest里的事件,新版本中已经不存在这样的问题了,老版本未测试。
    IE默认同时向一个站点发起的请求是两个,这个问题是我在做上传程序的时候遇到的,因为我同时向服务器发送三个请求,但最后一个一直得不到回应,只有等到前面两个结束后才能返回结果来。
    至于urlencode这个在js里面用encodeURIComponent这个函数,各种浏览器都可以的。“Content-Type= application/x-www-form-urlencoded; charset=UTF-8"这句话是告诉服务器,我发送的数据是urlencode过的。

  14. hzy said,

    December 31, 2005 @ 3:32 pm

    encodeURIComponent 在IE5.0里面没有,文档上这么说的,我没试过,所以结论下得比较武断。谢谢你耐心细致的解答。另外再跟你套个近乎,俺也是山东的。山东济南人。呵呵。 现在在青岛读研,也是26岁。呵呵。刚才好好看了你的blog一下发现了很多好东东,那个bindow,里面的图表功能很有意思,不过估计只能在IE下面 运行(vml)?
    今天很高兴,知道我有一个这么厉害的老乡。赞一个!

  15. hzy said,

    January 12, 2006 @ 12:04 pm

    你好,本来想直接copy你的生成xmlhttp对象的代码,发现有点问题。
    在IE下面也可以手工给window添加名为XmlHttpRequest的属性,如果用户代码中恰好有这么一个自定义的属性,这段代码就不能返回正确的对象了。也许就正如你所说,代码还有可以完善的地方。
    PS,看你的代码有种很high的感觉,自由而不放浪,英气逼人,呵呵。

  16. FindRain said,

    January 16, 2006 @ 10:29 am

    有一个问题,是否可以给每个请求指定超时时间,加上超时处理?

  17. mincyw said,

    January 17, 2006 @ 7:12 pm

    非常感谢,你的东东帮了我很大的忙!

  18. maltose said,

    January 19, 2006 @ 8:29 pm

    我想请教一个关于http://www.yule21.com/info/990.htm
    这篇文章说得这个问题,他是用vbscript解决的
    我想请问一下用javascript就一定没有办法解决了吗?
    盼望答案

  19. longbill said,

    April 23, 2006 @ 7:50 pm

    为什么blog文章的标题不能复制呢?奇怪

  20. Huangl said,

    April 29, 2006 @ 12:46 am

    为什么每次创建一个xmlHttprequest对象的代价需要考虑呢?即使浪费,不也是浪费clint端的那一点“小小”的性能么?对整个系统的性能会造成影响么?作者是否做过性能上的测试,或者有一些经验数据可以公布一下么?

  21. legend said,

    May 10, 2006 @ 1:30 am

    没有测试过也没有经验数据,只是认为ie每次创建activex对象应该是有些花销的。我这篇文章的主要目的并不是为了节能,而是为了并发。

  22. Huangl said,

    May 10, 2006 @ 1:59 am

    ??不创建一个池,就不能并发了么?
    还有,xmlhttprequest对象的生命周期有多长?每次从池中取出一个用就可以么?
    不好意思,新手,不明白的太多,呵呵。

  23. legend said,

    May 10, 2006 @ 2:06 am

    不创建也可以并发,但每次得创建一个新的xmlhttprequest对象。我创建池的目的,就是为了能够重复利用已经创建的对象。

    说到并发,ie默认是每个站点同时只允许两个线程的。

    这篇文章现在看来,还是有很多不妥的地方。

  24. nada said,

    May 12, 2006 @ 7:34 pm

    真高手,向你学习,顶一个。

  25. Zhang-Zi said,

    May 17, 2006 @ 3:12 am

    这东西不错。那个IE的Ajax缓存情况以前我遇到过,弄了我好久,到后来才发现IE的ajax会缓存。要是早看到你这篇文章就好了

  26. An said,

    June 6, 2006 @ 7:22 am

    一定要说声感谢!

  27. diaodiao said,

    November 5, 2006 @ 5:43 pm

    用你的代码在本地运行的时候就出现了状态代码是4 的时候回调函数没反应的情况,这个是怎么回事?

  28. diaodiao said,

    November 5, 2006 @ 8:08 pm

    o~~ 试验成功了,之前不知道是哪里搞错了,多谢多谢,救急了

  29. 海南马自达 said,

    December 13, 2006 @ 3:05 pm

    非常感谢

  30. Alan said,

    December 31, 2006 @ 11:31 am

    思 路很好,不过有个问题,IE 解释脚本的时候是顺序执行的,这就是说,他会沿你设计的脚本一步一步走下去! 而 xmlhttpRequst 则是个异步过程,这样,当下一步脚本调用前,xmlhttpResquest 总是还没有send,所以这个线程池最后也没起到作用,调用1次sendReq就多创建一个xmlHttpRequest,和没用池子几乎没什么差别

  31. legend said,

    December 31, 2006 @ 1:02 pm

    調用xmlhttprequest就發送了,然後下一次調用的時候,如果前面的都在使用中,會自動創建一個新xmlhttp對象。如果有空閒的對象才會直接使用它。

    這個池子並不是爲了效率,而是如果是單一的xmlhttprequest對象,重復調用的話,如果前一個正在發送,後面的就會覆蓋這個對象,那我們的請求就丟失了。

  32. streetsmart said,

    January 12, 2007 @ 3:03 am

    谢谢您,您给了很大帮助。

  33. kevin said,

    April 21, 2007 @ 6:55 pm

    使用中发现了一个问题。当我读取A完毕,并正确显示之后,点B,读取B的内容的时候,B可以正确显示,而A又会重新进入读取状态,而且始终无法完成,即staut始终=0。这是什么呢?怎么解决?

  34. kevin said,

    April 21, 2007 @ 6:59 pm

    我代码做过改动。改动如下:(注:showid是传入的值,每次都不一样,就是显示的地方。)
    onreadystatechange = function ()
    {
    if (objXMLHttp.readyState “;
    }
    if (objXMLHttp.readyState == 4 && (objXMLHttp.status == 200 || objXMLHttp.status == 304))
    {
    var response = objXMLHttp.responseText;
    document.getElementById(showid).innerHTML=response;

  35. legend said,

    April 21, 2007 @ 8:28 pm

    要不你就用这个吧: http://www.ugia.cn/?p=122

  36. huxishengming said,

    May 5, 2007 @ 3:58 pm

    objXMLHttp.readyState = 0;
    在ff中这样为对象添加一个属性可以吗?不是应该用addAttribute吗?

  37. zeroone said,

    May 12, 2007 @ 12:08 pm

    加入随机数怎么还是没有办法解决IE的缓存
    我用
    xmlHttp.abort();
    解决了

  38. 毛毛虫 said,

    May 22, 2007 @ 9:08 am

    ???10)uuu(0)iii(0)ooo(0)000(0)0i(0)0889(0)45677(0)0gk(0)hh(0)u(0)p(0);(0)
    ie下 请求页面得到的数据会出现如上的乱码 导致页面布局都乱了 请问这是怎么回事啊 xmlhttp.js里的中文注释我已经去掉了
    ff下一切正常

  39. legend said,

    May 22, 2007 @ 9:19 am

    你页面 编码是什么?

  40. 毛毛虫 said,

    May 22, 2007 @ 9:26 am

    html:

    New Document

    js:
    setRequestHeader(’Content-Type’, ‘application/x-www-form-urlencoded; charset=gb2312′);
    send(data);
    onreadystatechange = function ()
    {
    if (objXMLHttp.readyState == 4 && (objXMLHttp.status == 200 || objXMLHttp.status == 304))
    {
    //callback(objXMLHttp);
    alert(objXMLHttp.responseText);
    }
    }
    server端:asp

  41. 毛毛虫 said,

    May 22, 2007 @ 9:27 am

    server端:asp

  42. 毛毛虫 said,

    May 22, 2007 @ 9:28 am

    啊 不让发代码啊
    server端 asp:
    response.charset = “gb2312″

  43. 毛毛虫 said,

    May 22, 2007 @ 9:30 am

    客户端只是发送了一个请求页面 还没参数
    var u2 = “txlload/load_team_list.asp”;
    XMLHttp.sendReq(’GET’,u2,'’,callback); //打开页面时 加载分组

  44. 毛毛虫 said,

    May 22, 2007 @ 9:48 am

    问题找到了 是创建的xmlhttprequest对象问题
    我改成这样了:
    if(window.XMLHttpRequest){
    objXMLHttp = new XMLHttpRequest();
    if (objXMLHttp.overrideMimeType) {
    objXMLHttp.overrideMimeType(”text/xml”);
    }
    }
    else if (window.ActiveXObject){
    try {
    objXMLHttp = new ActiveXObject(”Msxml2.XMLHTTP”);
    } catch (e) {
    try {
    objXMLHttp = new ActiveXObject(”Microsoft.XMLHTTP”);
    } catch (e) {}
    }
    }
    if (!objXMLHttp) {
    window.alert(”can’t create XMLHttpRequest object.”);
    return null;
    }
    ie下也正常了 不过不知道是什么原因造成的

  45. Jeffy said,

    August 31, 2007 @ 10:40 am

    我比较支持用json,因为rpc有性能问题
    作者能告诉一下我QQ和MSN吗?
    UGiA PHP UPLOADER 怎么实现远程上传?我意思是说我网站在A服务器,在A服务器页面上操作时,怎么把文件上传到B服务器上!

  46. Jeffy said,

    August 31, 2007 @ 10:42 am

    上面发错地方了,应该发在 phprpc 那个里面

  47. hongyu said,

    August 31, 2007 @ 10:52 am

    写得真好,正想研究下并发的xhr呢,学习了,文档注释也很全,难得啊!

  48. 胡杨 said,

    October 24, 2007 @ 8:34 pm

    能还能逐行的解释一下。
    刚刚接触xmlhttprequest这方面的知识。
    切盼
    我的email:micenote@yahoo.com.cn

  49. irene said,

    December 12, 2007 @ 2:17 pm

    正好遇到这种问题,需要解决。这个方法很好用!

  50. 破曉之陽 said,

    December 28, 2007 @ 12:33 am

    其實在IE7.0 里面。
    if (window.XMLHttpRequest)
    {
    var objXMLHttp = new XMLHttpRequest();
    }
    如果把 var objXMLHttp = new XMLHttpRequest();

    //var objXMLHttp=new ActiveXObject(”Microsoft.XMLhttp”); 也是可行的。就是說。在IE7.0 里面。你先創建那個他就用那個。
    還有一個問題。就是當我們創建的是var objXMLHttp=new ActiveXObject(”Microsoft.XMLhttp”); 這個時候。responseText 這個東西可以用responsetext 就是說大小寫都可以的。
    但是如果是var objXMLHttp = new XMLHttpRequest(); 就必須是responseText。。。。 今天我就是給這個搞了好長時間。郁悶死了。

转载于:https://my.oschina.net/u/1246814/blog/225353

转载 Xmlhttprequest对象池相关推荐

  1. [转]建一个XMLHttpRequest对象池

    在ajax应用中,通常一个页面要同时发送多个请求,如果只有一个XMLHttpRequest对象,前面的请求还未完成,后面的就会把前面的覆盖掉,如果每次都创建一个新的XMLHttpRequest对象,也 ...

  2. java对象工厂池_[转载]Java对象池技术的原理及其实现

    作者:汪永好 出处:计算机与信息技术 责任编辑: 方舟 [ 2006-11-25 07:00 ] 摘 要 :本文在分析对象池技术基本原理的基础上,给出了对象池技术的两种实现方式.还指出了使用对象池技术 ...

  3. 建一个XMLHttpRequest对象池

    在ajax应用中,通常一个页面要同时发送多个请 求,如果只有一个XMLHttpRequest对象,前面的请求还未完成,后面的就会把前面的覆盖掉,如果每次都创建一个新的 XMLHttpRequest对象 ...

  4. ajax(判断浏览器创建xmlhttprequest对象),XMLHTTPRequest对象的创建与浏览器的兼容问题...

    MLHttpRequest 对象是AJAX功能的核心,要开发AJAX程序必须从了解XMLHttpRequest 对象开始. 了解XMLHttpRequest 对象就先从创建XMLHttpRequest ...

  5. Ajax异步XMLHttpRequest对象

    示例Ajax: <%@ page language="java" contentType="text/html; charset=utf-8"pageEn ...

  6. Java 程序优化之对象池

    对象池概念: 如果一个类被频繁请求使用,那么不必每次都生成一个实例,可以将这个类都一些实例保存到一个"池"中,待需要使用的时候直接从"池"中获取.这个" ...

  7. cocos对象池的使用

    enemy.js cc.Class({extends: cc.Component,properties: {enemySpeed: 0, //设置加速度 },//初始化当前节点的y坐标init: fu ...

  8. Delphi对象池MyObjectPool.pas

    对象池一般在服务端使用,所以稳定性是第一的. 欢迎提意见 unit uMyObjectPool;interfaceusesSyncObjs, Classes, Windows, SysUtils;ty ...

  9. Netty 高性能之道 - Recycler 对象池的复用

    前言 我们知道,Java 创建一个实例的消耗是不小的,如果没有使用栈上分配和 TLAB,那么就需要使用 CAS 在堆中创建对象.所以现在很多框架都使用对象池.Netty 也不例外,通过重用对象,能够避 ...

最新文章

  1. 关于java.util.LinkedHashMap cannot be cast to ......的解决办法
  2. 用 AI 分析蒙娜丽莎的微笑,情绪分析认为她没那么高兴
  3. centos7 yum 错误 This system is not registered with an entitlement server
  4. 深入浅出:Linux设备驱动之字符设备驱动
  5. 线性表(一)——顺序表
  6. 一级计算机word试题及答案,计算机一级考试试题及答案Word文档..doc
  7. matlab 工业相机 曝光时间_机器视觉入门——光源相机镜头
  8. 企业实战_14_MyCat跨分片查询_全局表
  9. Fiddler抓包工具之Filters(过滤器)进行会话过滤
  10. Kotlin — 运行代码片段(以轻量级方式编写和无需创建整个应用程序的方法)
  11. 2021桂花开得真晚,晚了将近一个月
  12. 【图像隐写】基于matlab FFT数字水印嵌入【含Matlab源码 1670期】
  13. 极客大学架构师训练营 大数据 GFS、MapReduce、BigTable,Hadoop HDFS Yarn HiveQL 第12次作业
  14. 基于热传导方程的高温作业专用服装设计(三)
  15. 这些mac软件可以提高办公效率
  16. 注册cad中文件未找到html,acad(2014CAD出现未找到acad文件 求解)
  17. 验证码Kaptcha的使用
  18. diy nas配置推荐2020_廉价NAS方案,手把手教你用淘汰主机安装黑群NAS
  19. 圆形数字时钟同时显示数字时钟、日期和星期特效
  20. 自己实现SDIO wifi Marvell8801/Marvell88w8801驱动 介绍(一) ---- 芯片介绍

热门文章

  1. windows2003系统的iis不能下载exe文件问题的解决
  2. [JavaME]手机申请移动分配的动态IP(3)?
  3. 创建sql自定义的函数及商品分页sql存储过程
  4. Windows 2008下安装配置 WDS Windows部署服务
  5. 十年技术,不要再迷茫
  6. scala 处理 Response返回 时间报错问题
  7. EventBus源码解析
  8. 下载和安装Nginx之配置选项
  9. 解决'ping' 不是内部或外部命令,也不是可运行的程序
  10. 策略模式——Strategy