2013-06-26 79 views
0

我在JavaScript中創建了一個http客戶端,它對單個非異步和異步GET和POST調用很好,但如果我多次調用makeRequest(),每個請求的響應都是相同的,同時發生非異步請求和異步請求。使用JavaScript的異步xmlHttpRequest httpClient

Service.aspx文件只是中繼參數名稱的值,因此應該針對每個請求進行更改。

這裏是JavaScript代碼:

///-- Usage examples ---------------------------------------------- 
/* 
//Full 
client = new httpClient(); 
client.method("get"); 
client.baseUrl("Service.aspx"); 
client.requestData({name: "John", age: 56, location: "Kansas City"}); 
var response = client.makeRequest(); 
alert(response); 

//Multiple requests 
client = new httpClient(); 
client.baseUrl("Service.aspx"); 

client.requestData("?q=foo"); 
var data = client.makeRequest(); 
alert(data); 

client.requestData("?q=foobar"); 
var data = client.makeRequest(); 
alert(data); 

//Minimal 
client = new httpClient(); 
client.baseUrl("Service.aspx?q=test"); 
client.makeRequest(); 

//Minimal, with deafult base URL http://localhost/ 
client = new httpClient(); 
client.requestData("?q=foobar"); 
client.makeRequest(); 

//Full, with response output contained in an object 
client = new httpClient(); 
client.method("get"); 
client.baseUrl("Service.aspx"); 
client.requestData("?q=test"); 
var requestObject = client.makeRequestObject(); 
alert(requestObject.MimeType); 
alert(requestObject.charset); 

//Custom callback function to handle asychronous httprequests 
myCallback = function (response) { 
    alert("myCallback: " + response); 
} 

client = new httpClient(); 

client.asynchronous(true); 
client.method("post"); 
client.baseUrl("Service.aspx"); 
client.requestData({ name: "John", age: 56, location: "Kansas City" }); 
client.callback(myCallback); 
client.makeRequest(); 

*/ 

function httpClient() { 
    this.$baseUrl = "http://localhost/"; 
    this.$method = "get"; 
    this.$response = ""; 
    this.$requestData = ""; 
    this.$asynchronous = false; 
} 

httpClient.prototype.method = function (requestMethod) { 
    this.$method = requestMethod; 
} 

httpClient.prototype.baseUrl = function (requestBaseUrl) { 
    this.$baseUrl = requestBaseUrl; 
} 

httpClient.prototype.requestResponse = function() { 
    return this.$response; 
} 

$_xmlhttpConstruct = function() { 
    var xmlhttp; 
    if (window.XMLHttpRequest) {//IE7+, Firefox, Chrome, Opera, Safari 
     return new XMLHttpRequest(); 
    } 
    else {//IE6, IE5 
     try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } 
     catch (e) { } 
     try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } 
     catch (e) { } 
     try { return new ActiveXObject("Microsoft.XMLHTTP"); } 
     catch (e) { } 
    } 
} 

httpClient.prototype.setRequestHeader = function (header, value) { 

} 

$_callbackFunction = null; 

httpClient.prototype.callback = function (func) { 
    $_callbackFunction = func; 
} 

$_invokeCallback = function (func, response) { 
    try { 
     func(response); 
    } 
    catch (e) { 

    } 
} 

httpClient.prototype.asynchronous = function (boolean) { 
    this.$asynchronous = boolean; 
} 

httpClient.prototype.makeRequest = function() { 

    //Initializing the xmlhttp object 
    var xmlhttp = $_xmlhttpConstruct(); 

    if (this.$requestData == undefined) { 
     xmlhttp.open(this.$method, this.$baseUrl, this.$asynchronous); 
    } 
    else { 
     if (this.$method == "post") { 

      xmlhttp.open(this.$method, this.$baseUrl, this.$asynchronous); 
      xmlhttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); 
      xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 
      xmlhttp.send(this.$requestData); 

      if (this.$asynchronous) { 
       xmlhttp.onreadystatechange = function() { 
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { 
         //Callback 
         $_invokeCallback($_callbackFunction, xmlhttp.responseText); 
        } 
       } 
      } 
      else { 
       return xmlhttp.responseText; 
      } 

      //alert("URL: " + this.$baseUrl + "\n" + "Method: " + this.$method + "\n" + "Request data: " + this.$requestData); 
     } 

     if (this.$method == "get") { 

      xmlhttp.open(this.$method, this.$baseUrl + this.$requestData, this.$asynchronous); 
      xmlhttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); 
      xmlhttp.send(null); 

      if (this.$asynchronous) { 
       xmlhttp.onreadystatechange = function() { 
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { 
         //Callback 
         $_invokeCallback($_callbackFunction, xmlhttp.responseText); 
        } 
       } 
      } 
      else { 
       return xmlhttp.responseText; 
      } 

      //alert("URL: " + this.$baseUrl + "\n" + "Full request URL: " + this.$baseUrl + this.$requestData + "\n" + "Method: " + this.$method + "\n" + "Request data: " + this.$requestData); 
     } 
    } 
} 

httpClient.prototype.makeRequestObject = function() { 

    var requestObject = { 
     method: this.$method, 
     url: this.$baseUrl, 
     requestData: this.$requestData, 
     responseData: "", 
     MimeType: "", 
     charset: "" 
    } 

    var xmlhttp; 
    if (window.XMLHttpRequest) {//IE7+, Firefox, Chrome, Opera, Safari 
     xmlhttp = new XMLHttpRequest(); 
    } 
    else {//IE6, IE5 
     xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); 
    } 

    if (this.$requestData == undefined) { 
     xmlhttp.open(this.$method, this.$baseUrl, false); 
    } 
    else { 
     //alert(this.$baseUrl + this.$requestData); 
     xmlhttp.open(this.$method, this.$baseUrl + this.$requestData, false); 
    } 

    if (this.$method == "post") { 
     xmlhttp.open(this.$method, this.$baseUrl, false); 
     xmlhttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); 
     xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 
     xmlhttp.send(this.$requestData); 

     //alert("URL: " + this.$baseUrl + "\n" + "Method: " + this.$method + "\n" + "Request data: " + this.$requestData); 
    } 
    if (this.$method == "get") { 
     xmlhttp.open(this.$method, this.$baseUrl + this.$requestData, false); 
     xmlhttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); 
     xmlhttp.send(); 

     //alert("URL: " + this.$baseUrl + "\n" + "Full request URL: " + this.$baseUrl + this.$requestData + "\n" + "Method: " + this.$method + "\n" + "Request data: " + this.$requestData); 
    } 

    var mc = xmlhttp.getResponseHeader("Content-Type"); 
    mc = mc.split(";"); 

    requestObject.MimeType = mc[0]; 
    requestObject.charset = mc[1].substring(9); 

    requestObject.responseData = xmlhttp.responseText; 

    return requestObject; 
} 

httpClient.prototype.requestData = function (data) { 

    if (typeof (data) == "object") { 
     var i = 0; 
     for (key in data) { 
      if (i == 0) { 
       if (this.$method == "get") { 
        this.$requestData += "?" + key + "=" + data[key]; 
       } 
       if (this.$method == "post") { 
        this.$requestData += key + "=" + data[key]; 
       } 
       i++; 
      } 
      else { 
       this.$requestData += "&" + key + "=" + data[key]; 
      } 
     } 
    } 
    else { 
     this.$requestData = data; 
    } 
} 

下面是如何使用客戶端(非異步):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html> 
    <head> 
     <title></title> 
    </head> 
    <body> 
     <div id="debug"></div> 

     <script type="text/javascript"> 

     useResponse = function (response) { 
      document.getElementById("debug").innerHTML += response; 
     } 

     client = new httpClient(); 

     client.method("get"); 
     client.baseUrl("Service.aspx"); 

     client.requestData({ name: "Peter", age: 45, location: "Kansas City" }); 
     useResponse(client.makeRequest()); 
     client.requestData({ name: "Paul", age: 76, location: "Kansas City" }); 
     useResponse(client.makeRequest()); 
     client.requestData({ name: "Mary", age: 36, location: "Kansas City" }); 
     useResponse(client.makeRequest()); 

     </script> 
    </body> 
</html> 

另一使用示例

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html> 
    <head> 
     <title></title> 
    </head> 
    <body> 
     <div id="debug"></div> 

     <script type="text/javascript"> 

      myCallback = function (response) { 
       document.getElementById("debug").innerHTML += response; 
      } 

      client = new httpClient(); 

      client.asynchronous(true); 
      client.method("get"); 
      client.baseUrl("Service.aspx"); 
      client.callback(myCallback); 

      client.requestData({ name: "Peter", age: 45, location: "Kansas City" }); 
      client.makeRequest(); 
      client.requestData({ name: "Paul", age: 76, location: "Kansas City" }); 
      client.makeRequest(); 
      client.requestData({ name: "Mary", age: 36, location: "Kansas City" }); 
      client.makeRequest(); 

     </script> 
    </body> 
</html> 

但內完成所有請求後,div的html是「PeterPeterPeter」。 它應該是「PeterPaulMary」或任何組合,具體取決於先完成哪些請求。

請任何幫助greric appriciated。

回答

0

我發現了這個錯誤。

httpClient.prototype.requestData = function (data) { 

     this.$requestData = ""; // <--- Fix 

     if (typeof (data) == "object") { 
      var i = 0; 
      for (key in data) { 
       if (i == 0) { 
        if (this.$method == "get") { 
         this.$requestData += "?" + key + "=" + data[key]; 
        } 
        if (this.$method == "post") { 
         this.$requestData += key + "=" + data[key]; 
        } 
        i++; 
       } 
       else { 
        this.$requestData += "&" + key + "=" + data[key]; 
       } 
      } 
     } 
     else { 
      this.$requestData = data; 
     } 
    }