Что произойдет, если ответ не получен для запроса? Я вижу повторы - программирование
Подтвердить что ты не робот

Что произойдет, если ответ не получен для запроса? Я вижу повторы

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

В моем клиентском коде я делаю вызов $.ajax. Это сообщение может занять некоторое время, чтобы ответить. То, что я вижу, - через некоторое время, когда запрос отправляется снова.

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

Я знаю, что мой сервер получает запрос более одного раза, когда я запустил Wireshark и могу видеть пост-запрос несколько раз. Итак, мое предположение заключается в том, что это связано с HTTP? I.e., если ответ не получен в течение определенного промежутка времени, тогда запрос будет повторно отправлен?

Вот пример моего вызова ниже.

$.ajax({
                    async: false,
                    type: 'POST',
                    url: '<%= url_for('importDevice') %>',
                    data: { device: val },
                    retryLimit: 0,
                    //callback
                    success: function(data) {
                    alert('calling import');
                    if ( data == 'nomaster')
                    {
                            // Display a warning  toast, with a title
                            toastr.warning('You must set the Master Key first!', 'Warning');
                            $.ismasterset = false;
                            //reset the form contents after added
                    } else
                    {
                            $("div#content").html(data);
                    }
                    },
                     beforeSend: function(){
                    alert('in before send');
                    }
            });

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

СОЕДИНЕНЬ с выходом от клиента и сервера.

ok Я установил "Live Http headers для Firefox".

На вкладке "Генератор" я вижу один единственный вызов

'#request# POST http://testhost/importdevice' 

Я не вижу POST в разделе "заголовки", может быть, потому что нет ответа?

На моем веб-сервере, хотя я вижу, что 2 вызова примерно на 22 секунды.

[Sun Jan 13 03:08:45 2013] [debug] POST /importdevice (Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:17.0) Gecko/20100101 Firefox/17.0).

[Sun Jan 13 03:09:07 2013] [debug] POST /importdevice (Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:17.0) Gecko/20100101 Firefox/17.0).

Я также вижу эти же вызовы в wirehark...

Вот почему я спрашивал, является ли это нормальным поведением, чтобы попытаться отправить запрос повторно, если ответ не вернется, аналогично рукопожатию TCP и ретрансляции SYN.

НОВОЕ ОБНОВЛЕНИЕ

Кажется, это не имеет никакого отношения к моему звонку Ajax. Если я создаю кнопку с простым HREF.

то есть

<a href="/importdevice?device=serverA" class="btn btn-success">TestDirect</a>

Затем в моем "Live HTTP headers output" я получаю... только один экземпляр.

#request# GET http://172.16.118.15/importdevice?device=serverA

Но еще раз в моих журналах сервера я получаю.

[Sun Jan 13 03:20:25 2013] [debug] GET /importdevice (Mozilla/5.0 (Macintosh; Intel Mac OS  X 10.8; rv:17.0) Gecko/20100101 Firefox/17.0).
[Sun Jan 13 03:20:48 2013] [debug] GET /importdevice (Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:17.0) Gecko/20100101 Firefox/17.0).

И в wirehark на сервере я вижу его дважды... и, как и ожидалось, мой серверный код вызывается дважды... Это ДЕЙСТВИТЕЛЬНО запутывает меня.

4b9b3361

Ответ 1

Ознакомьтесь с этим сообщением в блоге, в котором объясняется, что происходит: http://geek.starbean.net/?p=393

Согласно HTTP/1.1 RFC 8.2.4:

Если клиент HTTP/1.1 отправляет запрос, который включает тело запроса, но который не включает поле заголовка запроса Expect с ожиданием "100-продолжить", и если клиент напрямую не связан с HTTP/1.1, и если клиент видит, что соединение закрывается до получения какого-либо статуса с сервера, клиент ДОЛЖЕН повторить запрос.

Убедитесь, что вы создаете веб-приложение, чтобы терпеть эти дополнительные запросы. И если вы хотите, чтобы запрос ajax делал что-то только один раз, например, записывая что-то в базу данных, тогда вам нужно спроектировать запрос как idempotent. См.: Что такое идемпотентная операция?

Кроме того, это подчеркивает различия между операциями GET и POST: http://www.cs.tut.fi/~jkorpela/forms/methods.html

Как общая проектная практика:
-GET-операции должны быть разработаны как idempotent
Операции -POST должны использоваться для записи в базы данных и т.д.

Ответ 2

Почему вы устанавливаете обратный вызов, если ваш запрос не асинхронный?

Если вы хотите, чтобы процесс синхронизации отправил код beforeSend перед вызовом и обратный вызов успех просто после вызова.

Если вы хотите использовать асинхронный подход, установите async: true

Также эта строка кода неверна:

url: '<%= url_for('importDevice') %>',

Посмотрите на цитаты: должно быть

url: '<%= url_for("importDevice") %>',

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

Возвращаясь к вашему вопросу: Может быть, это браузер? Я не думаю, но кто знает, что там!... что за браузер? Вы пробовали с другим?

Я предлагаю попробовать с Firefox и использовать плагин Live httpHeaders (очень прост в настройке и использовании). Вы увидите, что происходит с клиентской стороны, чтобы увидеть, что происходит со стороны сервера.