AjaxRequest.js (独立库,只有这一个文件)

// ===================================================================
// Author: Matt Kruse <matt@ajaxtoolbox.com>
// WWW: http://www.AjaxToolbox.com/
//
// NOTICE: You may use this code for any purpose, commercial or
// private, without any further permission from the author. You may
// remove this notice from your final code if you wish, however it is
// appreciated by the author if at least my web site address is kept.
//
// You may *NOT* re-distribute this code in any way except through its
// use. That means, you can include it in your product, or your web
// site, or any other form where the code is actually being used. You
// may not put the plain javascript up on your site for download or
// include it in your javascript libraries for download.
// If you wish to share this code with others, please just point them
// to the URL instead.
// Please DO NOT link directly to my .js files from your site. Copy
// the files to your server and use them there. Thank you.
// ===================================================================

/**
 * The AjaxRequest class is a wrapper for the XMLHttpRequest objects which
 * are available in most modern browsers. It simplifies the interfaces for
 * making Ajax requests, adds commonly-used convenience methods, and makes
 * the process of handling state changes more intuitive.
 * An object may be instantiated and used, or the Class methods may be used
 * which internally create an AjaxRequest object.
 */
function AjaxRequest() {
 var req = new Object();
 
 // -------------------
 // Instance properties
 // -------------------

 /**
  * Timeout period (in ms) until an async request will be aborted, and
  * the onTimeout function will be called
  */
 req.timeout = null;
 
 /**
  * Since some browsers cache GET requests via XMLHttpRequest, an
  * additional parameter called AjaxRequestUniqueId will be added to
  * the request URI with a unique numeric value appended so that the requested
  * URL will not be cached.
  */
 req.generateUniqueUrl = true;
 
 /**
  * The url that the request will be made to, which defaults to the current
  * url of the window
  */
 req.url = window.location.href;
 
 /**
  * The method of the request, either GET (default), POST, or HEAD
  */
 req.method = "GET";
 
 /**
  * Whether or not the request will be asynchronous. In general, synchronous
  * requests should not be used so this should rarely be changed from true
  */
 req.async = true;
 
 /**
  * The username used to access the URL
  */
 req.username = null;
 
 /**
  * The password used to access the URL
  */
 req.password = null;
 
 /**
  * The parameters is an object holding name/value pairs which will be
  * added to the url for a GET request or the request content for a POST request
  */
 req.parameters = new Object();
 
 /**
  * The sequential index number of this request, updated internally
  */
 req.requestIndex = AjaxRequest.numAjaxRequests++;
 
 /**
  * Indicates whether a response has been received yet from the server
  */
 req.responseReceived = false;
 
 /**
  * The name of the group that this request belongs to, for activity
  * monitoring purposes
  */
 req.groupName = null;
 
 /**
  * The query string to be added to the end of a GET request, in proper
  * URIEncoded format
  */
 req.queryString = "";
 
 /**
  * After a response has been received, this will hold the text contents of
  * the response - even in case of error
  */
 req.responseText = null;
 
 /**
  * After a response has been received, this will hold the XML content
  */
 req.responseXML = null;
 
 /**
  * After a response has been received, this will hold the status code of
  * the response as returned by the server.
  */
 req.status = null;
 
 /**
  * After a response has been received, this will hold the text description
  * of the response code
  */
 req.statusText = null;

 /**
  * An internal flag to indicate whether the request has been aborted
  */
 req.aborted = false;
 
 /**
  * The XMLHttpRequest object used internally
  */
 req.xmlHttpRequest = null;

 // --------------
 // Event handlers
 // --------------
 
 /**
  * If a timeout period is set, and it is reached before a response is
  * received, a function reference assigned to onTimeout will be called
  */
 req.onTimeout = null;
 
 /**
  * A function reference assigned will be called when readyState=1
  */
 req.onLoading = null;

 /**
  * A function reference assigned will be called when readyState=2
  */
 req.onLoaded = null;

 /**
  * A function reference assigned will be called when readyState=3
  */
 req.onInteractive = null;

 /**
  * A function reference assigned will be called when readyState=4
  */
 req.onComplete = null;

 /**
  * A function reference assigned will be called after onComplete, if
  * the statusCode=200
  */
 req.onSuccess = null;

 /**
  * A function reference assigned will be called after onComplete, if
  * the statusCode != 200
  */
 req.onError = null;
 
 /**
  * If this request has a group name, this function reference will be called
  * and passed the group name if this is the first request in the group to
  * become active
  */
 req.onGroupBegin = null;

 /**
  * If this request has a group name, and this request is the last request
  * in the group to complete, this function reference will be called
  */
 req.onGroupEnd = null;

 // Get the XMLHttpRequest object itself
 req.xmlHttpRequest = AjaxRequest.getXmlHttpRequest();
 if (req.xmlHttpRequest==null) { return null; }
 
 // -------------------------------------------------------
 // Attach the event handlers for the XMLHttpRequest object
 // -------------------------------------------------------
 req.xmlHttpRequest.onreadystatechange =
 function() {
  if (req==null || req.xmlHttpRequest==null) { return; }
  if (req.xmlHttpRequest.readyState==1) { req.onLoadingInternal(req); }
  if (req.xmlHttpRequest.readyState==2) { req.onLoadedInternal(req); }
  if (req.xmlHttpRequest.readyState==3) { req.onInteractiveInternal(req); }
  if (req.xmlHttpRequest.readyState==4) { req.onCompleteInternal(req); }
 };
 
 // ---------------------------------------------------------------------------
 // Internal event handlers that fire, and in turn fire the user event handlers
 // ---------------------------------------------------------------------------
 // Flags to keep track if each event has been handled, in case of
 // multiple calls (some browsers may call the onreadystatechange
 // multiple times for the same state)
 req.onLoadingInternalHandled = false;
 req.onLoadedInternalHandled = false;
 req.onInteractiveInternalHandled = false;
 req.onCompleteInternalHandled = false;
 req.onLoadingInternal =
  function() {
   if (req.onLoadingInternalHandled) { return; }
   AjaxRequest.numActiveAjaxRequests++;
   if (AjaxRequest.numActiveAjaxRequests==1 && typeof(window['AjaxRequestBegin'])=="function") {
    AjaxRequestBegin();
   }
   if (req.groupName!=null) {
    if (typeof(AjaxRequest.numActiveAjaxGroupRequests[req.groupName])=="undefined") {
     AjaxRequest.numActiveAjaxGroupRequests[req.groupName] = 0;
    }
    AjaxRequest.numActiveAjaxGroupRequests[req.groupName]++;
    if (AjaxRequest.numActiveAjaxGroupRequests[req.groupName]==1 && typeof(req.onGroupBegin)=="function") {
     req.onGroupBegin(req.groupName);
    }
   }
   if (typeof(req.onLoading)=="function") {
    req.onLoading(req);
   }
   req.onLoadingInternalHandled = true;
  };
 req.onLoadedInternal =
  function() {
   if (req.onLoadedInternalHandled) { return; }
   if (typeof(req.onLoaded)=="function") {
    req.onLoaded(req);
   }
   req.onLoadedInternalHandled = true;
  };
 req.onInteractiveInternal =
  function() {
   if (req.onInteractiveInternalHandled) { return; }
   if (typeof(req.onInteractive)=="function") {
    req.onInteractive(req);
   }
   req.onInteractiveInternalHandled = true;
  };
 req.onCompleteInternal =
  function() {
   if (req.onCompleteInternalHandled || req.aborted) { return; }
   req.onCompleteInternalHandled = true;
   AjaxRequest.numActiveAjaxRequests--;
   if (AjaxRequest.numActiveAjaxRequests==0 && typeof(window['AjaxRequestEnd'])=="function") {
    AjaxRequestEnd(req.groupName);
   }
   if (req.groupName!=null) {
    AjaxRequest.numActiveAjaxGroupRequests[req.groupName]--;
    if (AjaxRequest.numActiveAjaxGroupRequests[req.groupName]==0 && typeof(req.onGroupEnd)=="function") {
     req.onGroupEnd(req.groupName);
    }
   }
   req.responseReceived = true;
   req.status = req.xmlHttpRequest.status;
   req.statusText = req.xmlHttpRequest.statusText;
   req.responseText = req.xmlHttpRequest.responseText;
   req.responseXML = req.xmlHttpRequest.responseXML;
   if (typeof(req.onComplete)=="function") {
    req.onComplete(req);
   }
   if (req.xmlHttpRequest.status==200 && typeof(req.onSuccess)=="function") {
    req.onSuccess(req);
   }
   else if (typeof(req.onError)=="function") {
    req.onError(req);
   }

   // Clean up so IE doesn't leak memory
   delete req.xmlHttpRequest['onreadystatechange'];
   req.xmlHttpRequest = null;
  };
 req.onTimeoutInternal =
  function() {
   if (req!=null && req.xmlHttpRequest!=null && !req.onCompleteInternalHandled) {
    req.aborted = true;
    req.xmlHttpRequest.abort();
    AjaxRequest.numActiveAjaxRequests--;
    if (AjaxRequest.numActiveAjaxRequests==0 && typeof(window['AjaxRequestEnd'])=="function") {
     AjaxRequestEnd(req.groupName);
    }
    if (req.groupName!=null) {
     AjaxRequest.numActiveAjaxGroupRequests[req.groupName]--;
     if (AjaxRequest.numActiveAjaxGroupRequests[req.groupName]==0 && typeof(req.onGroupEnd)=="function") {
      req.onGroupEnd(req.groupName);
     }
    }
    if (typeof(req.onTimeout)=="function") {
     req.onTimeout(req);
    }
   // Opera won't fire onreadystatechange after abort, but other browsers do.
   // So we can't rely on the onreadystate function getting called. Clean up here!
   delete req.xmlHttpRequest['onreadystatechange'];
   req.xmlHttpRequest = null;
   }
  };

 // ----------------
 // Instance methods
 // ----------------
 /**
  * The process method is called to actually make the request. It builds the
  * querystring for GET requests (the content for POST requests), sets the
  * appropriate headers if necessary, and calls the
  * XMLHttpRequest.send() method
 */
 req.process =
  function() {
   if (req.xmlHttpRequest!=null) {
    // Some logic to get the real request URL
    if (req.generateUniqueUrl && req.method=="GET") {
     req.parameters["AjaxRequestUniqueId"] = new Date().getTime() + "" + req.requestIndex;
    }
    var content = null; // For POST requests, to hold query string
    for (var i in req.parameters) {
     if (req.queryString.length>0) { req.queryString += "&"; }
     req.queryString += encodeURIComponent(i) + "=" + encodeURIComponent(req.parameters[i]);
    }
    if (req.method=="GET") {
     if (req.queryString.length>0) {
      req.url += ((req.url.indexOf("?")>-1)?"&":"?") + req.queryString;
     }
    }
    req.xmlHttpRequest.open(req.method,req.url,req.async,req.username,req.password);
    if (req.method=="POST") {
     if (typeof(req.xmlHttpRequest.setRequestHeader)!="undefined") {
      req.xmlHttpRequest.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
     }
     content = req.queryString;
    }
    if (req.timeout>0) {
     setTimeout(req.onTimeoutInternal,req.timeout);
    }
    req.xmlHttpRequest.send(content);
   }
  };

 /**
  * An internal function to handle an Object argument, which may contain
  * either AjaxRequest field values or parameter name/values
  */
 req.handleArguments =
  function(args) {
   for (var i in args) {
    // If the AjaxRequest object doesn't have a property which was passed, treat it as a url parameter
    if (typeof(req[i])=="undefined") {
     req.parameters[i] = args[i];
    }
    else {
     req[i] = args[i];
    }
   }
  };

 /**
  * Returns the results of XMLHttpRequest.getAllResponseHeaders().
  * Only available after a response has been returned
  */
 req.getAllResponseHeaders =
  function() {
   if (req.xmlHttpRequest!=null) {
    if (req.responseReceived) {
     return req.xmlHttpRequest.getAllResponseHeaders();
    }
    alert("Cannot getAllResponseHeaders because a response has not yet been received");
   }
  };

 /**
  * Returns the the value of a response header as returned by
  * XMLHttpRequest,getResponseHeader().
  * Only available after a response has been returned
  */
 req.getResponseHeader =
  function(headerName) {
   if (req.xmlHttpRequest!=null) {
    if (req.responseReceived) {
     return req.xmlHttpRequest.getResponseHeader(headerName);
    }
    alert("Cannot getResponseHeader because a response has not yet been received");
   }
  };

 return req;
}

// ---------------------------------------
// Static methods of the AjaxRequest class
// ---------------------------------------

/**
 * Returns an XMLHttpRequest object, either as a core object or an ActiveX
 * implementation. If an object cannot be instantiated, it will return null;
 */
AjaxRequest.getXmlHttpRequest = function() {
 if (window.XMLHttpRequest) {
  return new XMLHttpRequest();
 }
 else if (window.ActiveXObject) {
  // Based on http://jibbering.com/2002/4/httprequest.html
  /*@cc_on @*/
  /*@if (@_jscript_version >= 5)
  try {
   return new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e) {
   try {
    return new ActiveXObject("Microsoft.XMLHTTP");
   } catch (E) {
    return null;
   }
  }
  @end @*/
 }
 else {
  return null;
 }
};

/**
 * See if any request is active in the background
 */
AjaxRequest.isActive = function() {
 return (AjaxRequest.numActiveAjaxRequests>0);
};

/**
 * Make a GET request. Pass an object containing parameters and arguments as
 * the second argument.
 * These areguments may be either AjaxRequest properties to set on the request
 * object or name/values to set in the request querystring.
 */
AjaxRequest.get = function(args) {
 AjaxRequest.doRequest("GET",args);
};

/**
 * Make a POST request. Pass an object containing parameters and arguments as
 * the second argument.
 * These areguments may be either AjaxRequest properties to set on the request
 * object or name/values to set in the request querystring.
 */
AjaxRequest.post = function(args) {
 AjaxRequest.doRequest("POST",args);
};

/**
 * The internal method used by the .get() and .post() methods
 */
AjaxRequest.doRequest = function(method,args) {
 if (typeof(args)!="undefined" && args!=null) {
  var myRequest = new AjaxRequest();
  myRequest.method = method;
  myRequest.handleArguments(args);
  myRequest.process();
 }
} ;

/**
 * Submit a form. The requested URL will be the form's ACTION, and the request
 * method will be the form's METHOD.
 * Returns true if the submittal was handled successfully, else false so it
 * can easily be used with an onSubmit event for a form, and fallback to
 * submitting the form normally.
 */
AjaxRequest.submit = function(theform, args) {
 var myRequest = new AjaxRequest();
 if (myRequest==null) { return false; }
 var serializedForm = AjaxRequest.serializeForm(theform);
 myRequest.method = theform.method.toUpperCase();
 myRequest.url = theform.action;
 myRequest.handleArguments(args);
 myRequest.queryString = serializedForm;
 myRequest.process();
 return true;
};

/**
 * Serialize a form into a format which can be sent as a GET string or a POST
 * content.It correctly ignores disabled fields, maintains order of the fields
 * as in the elements[] array. The 'file' input type is not supported, as
 * its content is not available to javascript. This method is used internally
 * by the submit class method.
 */
AjaxRequest.serializeForm = function(theform) {
 var els = theform.elements;
 var len = els.length;
 var queryString = "";
 this.addField =
  function(name,value) {
   if (queryString.length>0) {
    queryString += "&";
   }
   queryString += encodeURIComponent(name) + "=" + encodeURIComponent(value);
  };
 for (var i=0; i<len; i++) {
  var el = els[i];
  if (!el.disabled) {
   switch(el.type) {
    case 'text': case 'password': case 'hidden': case 'textarea':
     this.addField(el.name,el.value);
     break;
    case 'select-one':
     if (el.selectedIndex>=0) {
      this.addField(el.name,el.options[el.selectedIndex].value);
     }
     break;
    case 'select-multiple':
     for (var j=0; j<el.options.length; j++) {
      if (el.options[j].selected) {
       this.addField(el.name,el.options[j].value);
      }
     }
     break;
    case 'checkbox': case 'radio':
     if (el.checked) {
      this.addField(el.name,el.value);
     }
     break;
   }
  }
 }
 return queryString;
};

// -----------------------
// Static Class variables
// -----------------------

/**
 * The number of total AjaxRequest objects currently active and running
 */
AjaxRequest.numActiveAjaxRequests = 0;

/**
 * An object holding the number of active requests for each group
 */
AjaxRequest.numActiveAjaxGroupRequests = new Object();

/**
 * The total number of AjaxRequest objects instantiated
 */
AjaxRequest.numAjaxRequests = 0;

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值