JQuery Ajax пост-запрос застрял в ожидании на Chrome

У меня есть клиент jQuery, который отправляет Ajax-запрос к Spring Controller. На стороне сервера не было зарегистрировано ни одной ошибки. На стороне клиента запрос задерживается на очень долгое время, минуты, а затем может завершиться с ошибкой либо с ERR_SPDY_PROTOCOL_ERROR, либо с ERR_CONNECTION_CLOSED.

Эта проблема воспроизводима в Chrome, но не в Firefox. Проверенная уязвимая версия - 70.0.3538.77, могут быть и другие. Кроме того, проблема возникает при конкретном развертывании приложения, а не в другом месте, разработке или производстве.

Клиент отправляет запросы HTTPS 2 в этой среде. В среде разработки это HTTP 1.1. На сервере все запросы записываются как 1.1.

Без видимой причины запросы начали проходить, но это повторяющаяся проблема, и мы хотели бы ее решить. Поскольку проблема начала возникать, я не могу воспроизвести ее и проверить, не является ли проблема слишком большим количеством подключений к серверу (более 6). Я использую три DNS-сервера, последний из которых - Google 8.8.8.8.

Я ищу исправление кода или подсказку, может ли это быть связано с настройкой сервера. Я почти уверен, что это комбинация клиентского кода и сетей.

В чем проблема не так:

Что я безуспешно пытался:

Что не отвечает на вопрос:

На стороне клиента я пытался очистить данные браузера, очистить сокеты и приватный просмотр/инкогнито.

Единственное, что иногда, редко, обходит ошибку - это инкогнито, очистка сокетов и очистка кеша из событий chrome://net-internals/#

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);
    }
});

Отдельный запрос с использованием $.post проходил через:

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

Сторона сервера:

@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();
}

Если это актуально, существуют следующие фильтры. Боюсь, я не могу опубликовать больше из них в данный момент:

@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 {

}

Ожидаемый результат состоит в том, что код должен пройти обратный вызов успеха. Вместо этого запрос застревает на ожидании в течение нескольких минут, затем вводится сообщение об ошибке.

Ответы

Ответ 1

$.post вызывает $.ajax под прикрытием, просто по умолчанию некоторые из параметров.

$.post умолчанию contentType значение "application/x-www-form-urlencoded; charset=UTF-8" что будет соответствовать вашей полезной нагрузке сериализованных данных формы.

Ваш вызов $.ajax устанавливает для contentType значение false что может привести к тому, что браузер отправит на сервер предварительный запрос OPTIONS перед полетом, что может привести к разнице в поведении, которое вы испытываете.

Я хотел бы предложить прочитать подробности о jQuery.ajax() и различные варианты поведения, основанные на опциях, переданных здесь.