Почему Internet Explorer не отправляет тело HTTP post на вызов Ajax после сбоя?

мы можем надежно воссоздать следующий сценарий:

  1. создайте небольшую HTML-страницу, которая делает запросы AJAX на сервер (используя HTTP POST)
  2. отключитесь от сети и снова подключите
  3. мониторинг пакетов, которые IE генерирует после сбоя

после неудачного сетевого подключения IE делает следующий запрос AJAX, но отправляет только HTTP-заголовок (не тело) при выполнении HTTP post. Эта причина всевозможные проблемы на сервере, так как это только частичный запрос. Google эта проблема с Bing, и вы найдете много людей, жалующихся на "случайные ошибки сервера", используя AJAX или необъяснимые сбои AJAX.

мы знаем, что IE (в отличие от большинства других браузеров) всегда отправляет HTTP-сообщение в виде двух пакетов TCP/IP. Заголовок и тело отправляются отдельно. В случае непосредственно после сбоя,IE отправляет только заголовок.

Итак, мой вопрос - почему вести себя так? Это кажется неправильным на основе спецификации HTTP, и другие браузеры не ведут себя таким образом. Это просто ошибка? Конечно, это создает хаос в любом серьезном веб-приложении на основе AJAX.

Справочная информация:

существует аналогичная проблема, вызванная таймаутами HTTP keep-alive, которые короче 1 минуты и документированы здесь:

http://us.generation-nt.com/xmlhttprequest-post-sometimes-fails-when-server-using-keep-aliv-help-188813541.html

http://support.microsoft.com/default.aspx?kbid=831167

вот захваты пакетов до и после сбоя:

обратите внимание, как отправляется HTTP-заголовок и полезная нагрузка http://img827.imageshack.us/i/beforee.png/

после сбоя обратите внимание, как только Заголовок отправлен. Т. е. никогда отправляет полезную нагрузку, и сервер в конечном итоге отвечает таймаутом. http://img203.imageshack.us/i/retryt.png/

6 ответов


  1. если HTTP Keep-Alive является отключен на сервере, эта проблема уходит. Другими словами, ваш сервер HTTP 1.1 будет отвечать на каждый запрос Ajax с Connection: Close строка в ответе. Это держит IE счастливым, но вызывает каждый Ajax запрос на открытие соединения. Это может иметь значительное влияние на производительность, особенно в сетях с высокой задержкой.

  2. проблема запускается легко, если запросы Ajax выполняются в быстрой последовательности. Например, мы делаем запросы Ajax каждые 100 мс, а затем изменяется состояние сети, ошибка легко воспроизводится. Хотя большинство приложений, вероятно, не делают таких запросов, у вас может быть несколько вызовов сервера, происходящих сразу после друг друга, которые могут привести к этой проблеме. Менее болтливый держит IE счастливым.

  3. это происходит даже без аутентификации NTLM.

  4. это происходит, когда ваш тайм-аут HTTP keep-alive на сервере короче, чем по умолчанию (который по умолчанию составляет 60 секунд в Windows). Подробности в ссылке в вопросе.

  5. Это не происходит с Chrome или Firefox. FF отправляет один пакет, поэтому, похоже, полностью избегает этой проблемы.

  6. Это происходит в IE 6, 7, 8. Не удалось воспроизвести с IE 9 beta.


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

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


У меня была аналогичная проблема, когда некоторые старые версии IE отправляли бы только заголовок, а не тело сообщения. Моя проблема оказалась связана с IE и NTLM. Поскольку вы не упомянули NTLM, это, вероятно, не поможет, но на всякий случай:

http://support.microsoft.com/kb/251404


Это длинный выстрел, но IE (и даже Firefox) иногда " помнит" соединение, используемое для HTTP-запроса. Примечания/примеры:

  • в Firefox, если я изменю настройки прокси-сервера и нажму SHIFT-перезагрузить страница, она все еще использует старый прокси. Однако, если я убью старого прокси ("killall squid"), он начинает использовать новый прокси.

  • при отключении / повторном подключении вы получаете новый IP-адрес или что-нибудь похожее? Может вы как-то монитор старый IP-адрес увидеть если IE отправляет данные на этот теперь мертвый адрес?

  • Я предполагаю, что IE отправляет данные, просто неправильно путь. Это может быть достаточно умно, чтобы не кэшировать сетевые подключения для Пакеты" POST", но могут быть недостаточно умными, чтобы сделать это для POST полезная нагрузка.

  • Это, вероятно, не влияет на большинство приложений AJAX, так как люди редко отключить и повторно подключиться к их сетям?


вы используете аутентификацию NTLM?

при использовании аутентификации NTLM IE не отправляет post-данные. Он отправляет информацию заголовка, ожидает несанкционированного ответа, отправляет авторизацию и после "повторной аутентификации" отправляет сообщение.


сегодня у меня была аналогичная проблема при использовании $.ajax и смог исправить это, установив async в false.

$.ajax({
  async: false, 
  url: '[post action url]',
  data: $form.serialize(),
  type: 'POST',
  success: successCallback
});