XmlHttpRequest returning state 4 too soon

558 views Asked by At

I'm developing a javascript code to run on an embedded device using the ANT Galio browser.

Ideally, I'd like the code to make a get request to another server. After that get request is made, the page would not allow the user to submit another get request, until a response had been received from the previous get request.

For some reason sometimes I am receiving a readyState of 4 almost instantly. It is as though it is evaluating the previous XmlHttpRequest object and not the new one. What am I doing wrong?

 <script type="text/javascript">

var fail= function (env, resp, stat) {

        alert(resp);
};
var succ= function (env, resp) {
};

var canScan = true;

/* start scan */
function scan (name) {
        if (canScan) {
                //deactivate button
                deactivateScanButtons();
                //let server know
                ajax = new XMLHttpRequest();
                var scanUrl = 'http://19X.1XX.X.XX:8080/scan/' + name
                ajax.open('GET', scanUrl, true);
                ajax.onreadystatechange = function() {
                        if (ajax.readyState==4) {
                                //allow button to work again
                                activateScanButtons();
                                alert("ready state 4");


                        };
                };

                ajax.send();
//initiate scan
                xrxScanInitiateScan(
                        'http://127.0.0.1',
                        "ftp.xst",
                        false,
                        succ,
                        fail);
        }

}

function deactivateScanButtons () {
//      canScan = false;

        var indicator = document.getElementById('buttons');
        indicator.style.visibility = "hidden";
}
function activateScanButtons () {
//      canScan = true;

        var indicator = document.getElementById('buttons');
        indicator.style.visibility = "visible";

}
</script>
2

There are 2 answers

0
Ekin Koc On BEST ANSWER

3 suggestions:

  1. To avoid any caching on the client side, add a randomly generated number, or the current timestamp to the request querystring.
  2. As Yoni said, initiate your XMLHttpRequest object with var keyword.
  3. For each request, save the current timestamp within a global variable. In onreadystatechange, call activateScanButtons only if the global timestamp matches the corresponding timestamp of that given request. This way, only the latest request will be able to call activateScanButtons.
0
Yoni On

You define the ajax object in scan function without the var keyword before it. This means that it is a global object, not local. Afterwards, you have a closure - you refer to that variable in the onreadystate callback function.

I find it hard to track exactly what's going on there, but I agree with you, as you say in your question, that the callback is not using the ajax object the way you expect. You say it happens sometimes - does it happen when you make two requests almost simultaneously (double-click a button or otherwise trigger the two get requests very fast)?

I suggest that you use the var keyword before defining the ajax object. Even better, try using this in the callback function instead of referring to the ajax object by name. If it works, you have spared yourself of one closure.