Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery Ajax post request stuck on pending on Chrome

I've got a jQuery client making an Ajax post request to a Spring Controller. On the server side, no error has been logged. On the client side, the request is stuck on pending a very long time, minutes, then might fail either with ERR_SPDY_PROTOCOL_ERROR or ERR_CONNECTION_CLOSED.

This problem is reproducible on Chrome, but not on Firefox. Verified affected version is 70.0.3538.77, there may be others too. Also, the problem occurs on a specific deployment of the application and not elsewhere, development or production.

The client sends HTTPS 2 requests on that environment. On the development environment it is HTTP 1.1. On the server, all requests are recorded as 1.1.

For no apparent reason, the requests started going through, but this is a recurring problem and would like to solve it. Since the problem started happening, I can't reproduce it and check if the problem is too many connections to the server (more than 6). I use three DNS servers, the last one of which is Google's 8.8.8.8.

I am looking for a code fix or a hint whether this could be related to server setup. I am almost certain that it is a combination of client code and networking.

What the problem is not:

  • Antivirus (Chrome net::ERR_INCOMPLETE_CHUNKED_ENCODING error)

  • Prediction service related (Stalled and pending ajax requests by JQuery in Chrome) - the comment about proxy and connections seems more relevant though.

  • Ad-blocker extension / plug-in (Failed to load resource under Chrome)

What I've tried unsuccessfully:

  • https://www.reddit.com/r/chrome/comments/3ej5ua/err_spdy_protocol_error/

  • https://www.itechgyan.com/err_spdy_protocol_error/

  • jQuery Ajax requests are getting cancelled without being sent

What doesn't answer the question:

  • Ajax request over https hangs for 40 seconds in chrome only

On the client side, I've tried clearing browser data, flushing sockets and private browsing / incognito.

The only thing that sometimes, rarely, bypasses the error is going on incognito and flushing sockets and emptying cache from chrome://net-internals/#events

var formData = new FormData();

formData.append( /* ... */ );

//...

$.ajax({
    type: "POST",
    url: "/somepath/update",
    cache: false,
    data: formData,
    contentType: false,
    processData: false,
    success: function(result) {
        //...
    },
    fail: function(result) {
        //....
    },
    error: function( jqXHR, textStatus, errorThrown ){
        alert(textStatus + ":" + errorThrown);
    }
});

A separate request using $.post was going through:

$.post("someotherpath/update", $("#someForm").serialize())
    .done(function (data) {
        //...
     })
     .fail(function (data) {
         //...
     })
     .always(function () {
         //...
     });

Server side:

@RequestMapping(value="/somepath/update", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
public @ResponseBody String update(ModelClass model) {
    JSONObject result = new JSONObject();
    //...
    return result.toString();
}

If it's relevant, there are the following filters. I'm afraid I can't post more of them at the moment:

@Configurable
public class Filter1 extends OpenEntityManagerInViewFilter implements Filter{

    public void doFilterInternal(HttpServletRequest httpReq, HttpServletResponse httpResp, FilterChain chain)
        throws ServletException, IOException {
        //...
    }
}


@Configurable
public class Filter2 extends OncePerRequestFilter implements Filter{

    public void doFilterInternal(HttpServletRequest httpReq, HttpServletResponse httpResp, FilterChain chain)
        throws ServletException, IOException {
        //...
    }
}

@Order(/* very small integer */)
public class Filter3 extends OncePerRequestFilter {

}

Expected result is that the code should go through the success callback. Instead the request is stuck on pending for minutes, then enters the error callback.

like image 294
N Sarj Avatar asked Dec 21 '18 10:12

N Sarj


1 Answers

$.post is calling $.ajax under the covers just defaulting several of the options.

$.post defaults contentType to "application/x-www-form-urlencoded; charset=UTF-8" which would be consistent with your serialized form data payload.

Your call to $.ajax sets contentType to false -- which may cause the browser to send a pre-flight OPTIONS request to the server, which may be causing the difference in behavior you're experiencing.

I would suggest reading the details on jQuery.ajax() and the various behaviors based on options passed here

like image 144
Michael Angstadt Avatar answered Oct 22 '22 13:10

Michael Angstadt