3

I am submitting a form via ajax (using JQuery) and the time taken for the response to be received can be anything from a few seconds to a few minutes. This is expected and cannot be changed. This is working fine in all browsers except the stock Android browser which is timing out my request after 120 seconds, no matter what I set the timeout to in the ajax constructor. Is there a way around this?

The code for the Ajax request is quite simple:

var jqxhr = $.ajax({
    type: 'post',
    timeout: 500000,
    url: 'process.php',
    data: $('form').serialize(),
    success: function (data) {
    alert("success" + data);    
    },
    error: function(xhr, error){
    alert("Error: " + error + ", XHR status: " + xhr.status);
    },
   });

When submitted on Android with a script that takes over 120 seconds, the error handler is hit with the following message:

Error: error, XHR status: 0
Macros
  • 7,099
  • 2
  • 39
  • 61

5 Answers5

1

Please have a look at this article indicating that the error may arise from the presence of a HTTP Expires header.

Use a tool like Fiddler to monitor the HTTP network traffic and present the results for further analysis.

You have a syntax error.

var jqxhr = $.ajax({
    type: 'post',
    timeout: 500000,
    url: 'process.php',
    data: $('form').serialize(),
    success: function (data) {
    alert("success" + data");   <------- HERE   
    },
    error: function(xhr, error){
    alert("Error: " + error + ", XHR status: " + xhr.status);
    },
   });

Try your code with this on-line JavaScript runner but remove the extra double qoute.

var jqxhr = $.ajax({
    type: 'post',
    timeout: 500000,
    url: 'process.php',
    data: $('form').serialize(),
    success: function (data) {
    alert("success" + data);
    },
    error: function(xhr, error){
    alert("Error: " + error + ", XHR status: " + xhr.status);
    },
   });
Ben Crowhurst
  • 8,204
  • 6
  • 48
  • 78
  • I've updated this in the question - the error was not present in my live code, just when I copied over to SO. Good spot but the code works fine, it is just the Android timeout issue I'm trying to resolve – Macros Jan 21 '14 at 17:46
  • Is the JavaScript in question served up by the same web server as process.php? I'm wondering if you're attempting a cross-origin call? – Ben Crowhurst Jan 28 '14 at 12:43
  • It is on the same server yes – Macros Jan 28 '14 at 13:16
0

After some research it appears that others have had similar issues with AJAX timeouts at ~60ms and ~120ms. Those seem like very deliberate values (like internal browser settings), and I am going to go ahead and assume from the lack of responses/solutions that we can't get around those timeouts.

Have you considered posting your AJAX request to a separate server/service which does not do any processing and can return a quick 200 OK response. Then let this second server handle the communication with the slow server. I know this sucks, but it might be your only solution (and might result in a snappier app and happier users).

Can you give any more insight into your app? Is this a PhoneGap app or is the app hosted at some domain that you can access from the browser? Are you able to provide a URL?

Ryan Wheale
  • 26,022
  • 8
  • 76
  • 96
0

Have you seen the below thread.

AJAX (XmlHttpRequest) timeout length by browser

Regards,

SP

Community
  • 1
  • 1
Roxx
  • 3,738
  • 20
  • 92
  • 155
0

Try inserting your code on a separate blank html page with nothing but your ajax request, jquery attached and some basic alerts like success, status code or errors etc. Put the correct file path in url handler, in data handler, put some static values like name:"Macros",site:"stackoverflow". When all gets ready, you should get alert message on desktop browser, if its success, try running that html page on stock android browser. If that works as well.. The problem might be jquery conflict with some other script or your $("form#testform").serialize() function.

-1

How about if you retry after the timeout?

$("form#testform").submit(function(){ 

    var allFormValues = $("form#testform").serialize(); 

    $.ajax({
        cache:false,
        timeout:8000,  // I chose 8 secs for kicks
        tryCount : 0,
        retryLimit : 5,
        type:"POST",
        url:"someurl.php",
        data:allFormValues,

        error:function(xhr, status, error) { 
            if (status == 'timeout') {
                this.tryCount++;
                if (this.tryCount <= this.retryLimit) {
                    alert("Timeout! Retrying now!");
                    //try again
                    $.ajax(this);
                    return;
                }            
                return;
            } else {
                // not a timeout? not a problem
                alert("Error: " + status + ", XHR status: " + xhr.status);
            }
        },
        success:function(response){
            alert(response);
        }
    });
});
Josue Alexander Ibarra
  • 8,269
  • 3
  • 30
  • 37
  • I don't really want to resubmit the request as there is a lot that goes on at this stage an some of it is on a remote server which I have no control over – Macros Jan 27 '14 at 09:37
  • this solution won't fix problem - second try will be interrupted after 120 sec again – Oleksii K. Jan 27 '14 at 09:38
  • May I ask what is your backend doing? and what stack are you using? It is a better option if you can do a push to device with websockets instead of comet (long polling) http://stackoverflow.com/questions/10028770/html5-websocket-vs-long-polling-vs-ajax – Josue Alexander Ibarra Jan 27 '14 at 17:23