ajax post request failing after third times on iOS

Viewed 174

I'm having a Node.js express app.

On a specific view, I have a recurrent ajax post-call, which is checking the status of a process. On the response, if it needs to be checked again there is a timeout of 5 seconds before checking again.

It's working well on the desktop and mobile none IOS However, as soon as I tried it on an iOS mobile it failed on the third request. (the first two worked well)

I checked different browser on the iPhone and each time is the same.

I'm having the following response from the call

{"readyState": 0, "status":0, "statusText": "error"}

It seems to be the case on every iOS devices. But it's working everywhere else (android, windows) Any ideas where it could come from? Very weird that it's happening working well for the first two calls and then somehow get blocked.

JS CODE OF THE REQUEST :

const checkUpdate =  (amount, ref, status) => {
        $.post({
            type: "POST",
            url: "/check-update-transaction",
            data: { amount, ref, status},
            headers: {
                "CSRF-Token": token,
            },
        }).done(
            (res) => {
                console.log(JSON.stringify(res));
                setTimeout(() => {
                    switch (parseInt(res.status))   {

                        case 1:
                            
                            return checkUpdate(amount, ref, 1);
                        case 2:
                            
                            return checkUpdate(amount, ref, 2);
                        case 3:
                            
                            $("#circle-loader-popup").hide();
                            return true;
                            
                    }

                }, 5000);

            }
        ).fail((error) => {
            $(".status-information .main-content-loader")
                .html(`A problem happened during the submission please try again `);
            console.log(JSON.stringify(error));
            if(error.responseJSON && error.responseJSON.notFind === true){
                $("#after-first-step").hide();
            }
        });
    };

Thanks in advance,

Anselme

1 Answers

Since there seems te be some confusion, reading your comments to your question, I think it would be handy to clear the confusion with this answer.

The problem with your question is, is that this response has nothing to do with the ajax request:

{"readyState": 0, "status":0, "statusText": "error"}

Here you see readyState, which coincidentally is also a property of the XMLHTTPRequest object.

So, how does the jQuery post method work and where does the XMLHTTPRequest come in?

Well, jQuery has its own implementation of the XMLHTTPRequest object: the jQuery XHR object, or jqXHR. This is the same object, but with some added functionality. It has Promise like features.

The post method actually returns a jqXHR object:

var thejqXHR = $.post(url);
console.log(thejqXHR.readyState); //1

The readyState here is 1: open() has been called., because post immediately calls open on the jqXHR object. In other words: it can never be 0, since it is opened right away.

Since the jqXHR object works a like promise we can then do done.

var thejqXHR = $.post(url);
thejqXHR.done(function(data, textStatus, jqXHR){
    console.log(data); //the data returned by the server
    console.log(textStatus); // always 'success'
    console.log(jqXHR.readyState);// always 4
});

The done method of the jqXHR object is called on success. Meaning the request was successful: the url is valid, the request reached the server, the server sent a valid response, of which the data is passed to the done method. And the XHR.readySate is 4: The operation is complete.

If something goes wrong, the done method is not called. The promise is rejected, so the fail method is called.

thejqXHR.fail(function(jqXHR, textStatus, errorThrown){
    console.log(jqXHR.readyState); // always '4'
    console.log(textStatus); // always 'error'
    console.log(errorThrown); // for example 'Not Found'
});

Here you see, again, that the readyState is 4: The operation is complete, the request was sent, it did not resolve for some reason, the fail method is called and the operation is complete (but with an error). The errorThrown is what you need to investigate to find our what went wrong.

To summarize: the XHR.readyState is pretty useless when using jQuery's post method. It is either 1 (opened) when the request has just been started, or it is '4' when the request is finished (either successfully or failed).

So, back to your line:

{"readyState": 0, "status":0, "statusText": "error"}

This has nothing to do with the XMLHTTPRequest.readyState. The XMLHTTPRequest.readyState is 4 when the request has finished. What you are dealing with here is the successful response from the server. It is the data that the server sends back and is passed to the success (done) function. In other words the request went perfectly well. The server's address was found, the server returns a valid response and it is passed back to you.

Now, why the server successfully responds with the above line, I don't know. This completely depends on the server side code that generates this line. The code you posted in your question has nothing to do with it. It is the server side code that you should investigate and find out why it returns this string with readyState: 0.

Hope it is a bit clearer now...

Related