最近开始学JavaScript这个问题,已经有不少解决方案了,可以说是不胜枚举。大多都集成进框架里面了,直接用的话,学不到东西。
所以,自己以学习为目的,整了点东西。欢迎大家来讨论,或者说“赐教”更好一些(因为目的是想听高人们讲解的,嘿嘿)。具体在我第一篇博客里面(汗):http://blog.csdn.net/OuDii/archive/2009/01/09/3741418.aspx这里仅贴出源代码:/****************************************************************************************************
                              Ajax请求类
作者:刘光
日期:2008-11-06
使用方法:  一、异步请求:
    var ajax = new LGAjax();
    ajax.Request(url,onSuccess[,timeOut[,onError[,onRequesting]]]);
    
    url:         请求的URL地址
    TimeOut:     超时时间
    onSuccess:   函数引用,请求成功时调用
    onError:     函数引用,请求失败时调用
    onRequesting:函数引用,请求冲突时调用(即上次请求未结束,又尝试新的请求) onSuccess函数里可通过
ajax.responseBody;(在函数内能访问到ajax)
    onSuccess.arguments[0].responseBody;(函数内访问不到ajax)
    
    二、同步请求
    var ajax = new LGAjax();
    ajax.IsAsync = false;
    ajax.Request(url);
    
    获取请求结果:
    ajax.responseBody;
    ajax.responseStream;
    ajax.responseText;   
    ajax.responseXML;  
    
公有数据成员: 
    RequestURL     string    请求的URL地址,默认是null
    TimeOut        number    请求的超时时间,默认是3000 
    RequestMethod  string    http方法,POST、GET、PUT及PROPFIND,默认是"POST"
    IsAsync        boolean   是否是异步请求,默认为true;
    PostData       不定      send()的数据,默认为null
responseBody;
    responseStream;
    responseText;   
    tresponseXML;   公有函数成员:
    setRequestHeader(name,value) 设置请求头部
    getResponseHeader(name);     获取请求头部
    getAllResponseHeaders();     返回所有请求头部
    
    注:函数参数运行时第一个参数为Ajax对象的引用
****************************************************************************************************/
function LGAjax()
{
    this.RequestURL = null;       //请求的URL地址
    this.TimeOut = 3000;          //请求超时时间,默认3秒
    this.RequestMethod = "POST";  //请求方法,默认为POST
    this.IsAsync = true;          //是否是异步请求,默认为true
    this.PostData = null;         //send的数据
this.Requesting = false;      //标识当前是否正在请求
    
    this.responseBody = null;
    this.responseStream = null;
    this.responseText = null;   
    this.responseXML = null;   
     
    var _OnSuccess = null;
    var _OnError = null;
    var _OnRequesting = null;
    
    var _Heads = new Object();     //用来保存用户设置的所有请求头部
    var _MySelf = this;            //当前LGAjax对象的引用
    var _TimerID = 0;              //监视当前异步请求定时器ID;
    var _XMLHttpRequest = null;    //请求对象
if(typeof(LGAjax._initialized)== "undefined")
{
//创建请求对象
LGAjax.prototype._CreateXMLHttpRequest = function()
{
if(window.XMLHttpRequest)
{
_XMLHttpRequest = new XMLHttpRequest();
if(_XMLHttpRequest.overrideMimeType)
{
_XMLHttpRequest.overrideMimeType("text/xml");
}
}
else if(window.ActiveXObject)
{
try
{
_XMLHttpRequest = new ActiveXObject("Msxml4.XMLHTTP");
}
catch(e)
{
try
{
_XMLHttpRequest = new ActiveXObject("Msxml3.XMLHTTP");
}
catch(e)
{
try
{
_XMLHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
}
catch(e)
{
try
{
_XMLHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(e)
{}
}
}
}
}
}; LGAjax.prototype._HandleStateChange = function()
{
//请求不成功,则为失败;在超时方法里调用错误方法
if(_XMLHttpRequest.readyState == 4 && _XMLHttpRequest.status == 200)
{
_MySelf.responseBody = _XMLHttpRequest.responseBody;
_MySelf.responseStream = _XMLHttpRequest.responseStream;
_MySelf.responseText = _XMLHttpRequest.responseText;   
_MySelf.responseXML = _XMLHttpRequest.responseXML;  

_MySelf.Requesting = false;
clearTimeout(_TimerID);
if(typeof _OnSuccess == "function")
{
_OnSuccess(_MySelf);
}
}
};
LGAjax.prototype.setRequestHeader = function(key,value)
{
_Heads[key] = value;
};
LGAjax.prototype.getResponseHeader = function(key)
{
return _XMLHttpRequest.getResponseHeader(key);
};
LGAjax.prototype.getAllResponseHeaders = function()
{
return _XMLHttpRequest.getAllResponseHeaders();  
};
LGAjax.prototype._TimeOut = function()
{
if(!(_XMLHttpRequest.readyState == 4 && _XMLHttpRequest.status == 200))
{
_XMLHttpRequest.abort();
_MySelf.Requesting = false;
if(typeof _OnError == "function")
{
_OnError(_MySelf);
}
}
}
LGAjax.prototype.Request = function(url,onSuccess,timeOut,onError,onRequesting)
{
if(!_MySelf.Requesting) //如果当前没有正在请求,则发起新的请求
{
_MySelf.RequestURL = url;
_MySelf.TimeOut = timeOut;

_OnSuccess = onSuccess;
_OnError = onError;
_OnRequesting = onRequesting;

if(_XMLHttpRequest == null)
{
_MySelf._CreateXMLHttpRequest();
}

_XMLHttpRequest.open(_MySelf.RequestMethod,_MySelf.RequestURL, _MySelf.IsAsync);
if(_MySelf.RequestMethod.toLowerCase() == "post")
{
_XMLHttpRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
}
for(var key in _Heads)
{
_XMLHttpRequest.setRequestHeader(key,_Heads[key]);
}

_XMLHttpRequest.onreadystatechange = _MySelf._HandleStateChange;
   
if(_MySelf.IsAsync)
{//如果是异步请求,监视是否超时
_TimerID = setTimeout(_MySelf._TimeOut,_MySelf.TimeOut);
}
_XMLHttpRequest.send(_MySelf.PostData);
if(_MySelf.IsAsync)
{
_MySelf.Requesting = true;
}
else
{//同步请求
_MySelf.responseBody = _XMLHttpRequest.responseBody;
_MySelf.responseStream = _XMLHttpRequest.responseStream;
_MySelf.responseText = _XMLHttpRequest.responseText;   
_MySelf.responseXML = _XMLHttpRequest.responseXML;  
}
}
else
{
if(typeof _OnRequesting == "function")
{
_OnRequesting(_MySelf);//上次请求尚未结束
}
}
};
LGAjax._initialized = true;
}
}

解决方案 »

  1.   

    给你几个建议把,首先,没有对status!=200的处理,比如404、500这种常见的状态码,建议至少向回调函数中throw一个信息。第二,没有参数设定回调方法的作用域,这个是很不合理的。第三,你这个是单例的吧?不是很实用哦。如果要发起多请求怎么办呢?所以,建议做一个连接池,管理请求的排队。给你一个我项目里用到的方法:ClientSys.io.ConnectionPool = {

    _queue:[], //Tasks queue

    _requests:[], //Request pool

    maxThread:2,

    _getIdleRequest:function(){
    var request = null;
    for(var i=0;i<this.maxThread;i++){
    if(this._requests[i].readyState == 0){
    request = this._requests[i];
    break;
    }
    }
    return request;
    },

    init:function(max){
    if(max!=null) this.maxThread = max;
    for(var k=0;k<this.maxThread;k++){
    var request = null;
    if (window.XMLHttpRequest){  // if Mozilla Safari etc
    request = new XMLHttpRequest();
    }else if (window.ActiveXObject){  // if IE
    try {
    request = new ActiveXObject("Msxml2.XMLHTTP");
    }catch (e){
    try{
    request = new ActiveXObject("Microsoft.XMLHTTP");
    }
    catch (e){
    request = null
    }
    }
    }
    this._requests.push(request);
    }
    },

    send:function(method,url,data,callback,scope){
    var request = this._getIdleRequest();
    if(request!=null){ //There is a idle request
    var handler = {func:callback,scope:scope};
    if(method.toLowerCase()=="get"){ //add a timestamp to abort the browser cache
    if(url.indexOf("?")>0) url += ("&timestamp="+new Date().getTime());
    else url += ("?timestamp="+new Date().getTime());
    }
    request.open(method,url,true);
    if(method.toLowerCase()=="post") request.setRequestHeader("Content-type","application/x-www-form-urlencoded;");
    else request.setRequestHeader("Content-type","text/xml");
    request.onreadystatechange = function(){
    if(request.readyState==4){
    if(request.status == 200){
    if(handler.func!=null){
    handler.func.call(handler.scope!=null?handler.scope:window,request.responseText,request.responseXML,request.status);
    }
    request.abort();
    if(LinkPool._queue.length>0){ //There is some tasks in waiting,do the first task;
    var task = LinkPool._queue.shift();
    LinkPool.send(task.method,task.url,task.data,task.callback,task.scope);
    }
    }else{
    (function(){throw request.status}).call(handler.scope!=null?handler.scope:window);
    }
    }
    }
    request.send(data);
    }else{ //All request are busy,push the task into the waiting queue;
    var task = {method:method,url:url,data:data,callback:callback,scope:scope};
    this._queue.push(task);
    }
    }
    }用的时候首先ClientSys.io.ConnectionPool.init(2) //设定最大连接数,不要超过2,在ie6中实例化2个以上请求对象会浏览器崩溃
    然后 ClientSys.io.ConnectionPool.send(method,url,data,callback,scope)
      

  2.   

    哦,上面发错版本了,重新发一个:var LinkPool = {

    _queue:[], //Tasks queue

    _requests:[], //Request pool

    maxThread:2,

    _getIdleRequest:function(){
    var request = null;
    for(var i=0;i<this.maxThread;i++){
    if(this._requests[i].readyState == 0){
    request = this._requests[i];
    break;
    }
    }
    return request;
    },

    init:function(max){
    if(max!=null) this.maxThread = max;
    for(var k=0;k<this.maxThread;k++){
    var request = null;
    if (window.XMLHttpRequest){  // if Mozilla Safari etc
    request = new XMLHttpRequest();
    }else if (window.ActiveXObject){  // if IE
    try {
    request = new ActiveXObject("Msxml2.XMLHTTP");
    }catch (e){
    try{
    request = new ActiveXObject("Microsoft.XMLHTTP");
    }
    catch (e){
    request = null
    }
    }
    }
    this._requests.push(request);
    }
    },

    send:function(method,url,data,callback,scope){
    var request = this._getIdleRequest();
    if(request!=null){ //There is a idle request
    var handler = {func:callback,scope:scope};
    if(method.toLowerCase()=="get"){ //add a timestamp to abort the browser cache
    if(url.indexOf("?")>0) url += ("&timestamp="+new Date().getTime());
    else url += ("?timestamp="+new Date().getTime());
    }
    request.open(method,url,true);
    if(method.toLowerCase()=="post") request.setRequestHeader("Content-type","application/x-www-form-urlencoded;");
    else request.setRequestHeader("Content-type","text/xml");
    request.onreadystatechange = function(){
    if(request.readyState==4){
    if(request.status == 200){
    if(handler.func!=null){
    handler.func.call(handler.scope!=null?handler.scope:window,request.responseText,request.responseXML,request.status);
    }
    request.abort();
    if(LinkPool._queue.length>0){ //There is some tasks in waiting,do the first task;
    var task = LinkPool._queue.shift();
    LinkPool.send(task.method,task.url,task.data,task.callback,task.scope);
    }
    }else{
    (function(){throw request.status}).call(handler.scope!=null?handler.scope:window);
    }
    }
    }
    request.send(data);
    }else{ //All request are busy,push the task into the waiting queue;
    var task = {method:method,url:url,data:data,callback:callback,scope:scope};
    this._queue.push(task);
    }
    }
    }
      

  3.   

     不知道 楼主现在封装的ajax怎么样了?