简体   繁体   中英

Asynchronous xmlHttpRequest using JavaScript httpClient

I have made a http client in JavaScript, its working fine for single non-asynchronous and asynchronous GET and POST calls, but if i call makeRequest() multiple times, the response is the same for each request, this happens with both non-asynchronous and asynchronous requests.

The Service.aspx file just relays the value of the parameter name, so that should change for each request.

Here is the JavaScript code:

///-- 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;
    }
}

Here is how i use the client (Non-asynchronous):

<!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>

Another usage example

<!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>

But the inner html of the div is "PeterPeterPeter" upon completion of all the requests. It should be "PeterPaulMary" or any combination, depending on what requests get completed first.

Please any help is greately appriciated.

I found the bug.

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;
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM