Masiar
Masiar

Reputation: 21352

xmlhttp request has strange behavior and has status = 0

I have a Google Chrome extension that upon pressing a button executes an xmlhttp request to a server. I'm currently handling the error if the server is down. What I want to achieve is to retry the request after an increasing number of seconds. That's how I do it:

var execute = function(method, url, i){
            //if timeout doesn't exist, create one
            if(!i){
                i = 1000;
            }

            var xmlhttp = new XMLHttpRequest(); 
            xmlhttp.open(method, url, true);

            xmlhttp.onreadystatechange = function(){
                if (xmlhttp.status != 200)  {
                    // Handle error, retry request
                    console.log("xmlhttp.status = " + xmlhttp.status + " and xmlhttp.readyState = " + xmlhttp.readyState);
                    setTimeout("execute('"+method+"', '"+url+"', "+i*2+")", i);
                    return;
                }
            };

            xmlhttp.send(null);
        }

Basically if there is some kind of problem I retry again the request. If the server is up, there is no problem at all, but if the server is down JavaScript throws me an error saying:

PUT http://localhost:3000/buy/2/id=1329664820124 
executepopup.html:127
(anonymous function)

Which is not really meaningful, but however. The status in the log says "0", which is pretty lame too. If I turn on the server again while this is going on, it should stop doing this, but instead also if it succeeds (I see a log in the server that tells me that it received the request), it keeps calling the execute method. I don't know how to stop this recursion if the server turns on. Am I doing something wrong? Is this state equal zero the problem?

Thanks a lot

Upvotes: 0

Views: 451

Answers (1)

Rob W
Rob W

Reputation: 348982

Solving the problem

onreadystatechange is triggered for every state change, from state 0 to 4, and many times between. You should only be interested in readyState 4, because the request has fully finished at that point.
To get your method to work, check whether xmlhttp.readyState == 4:

xmlhttp.onreadystatechange = function() {
    if (xmlhttp.readyState == 4 && xmlhttp.status != 200)  {


Fixing your horrible implementation of setTimeout

setTimeout("execute('"+method+"', '"+url+"', "+i*2+")", i); is not the right way to call a function again. Since you're developing in a Chrome extension, you can use the following format for setTimeout:

setTimeout(execute, i, method, url, i*2);
// Calls execute(method, url, i*2) after i milliseconds.

Upvotes: 4

Related Questions