Dlaczego Internet Explorer nie wysyła HTTP POST po wywołaniu Ajax po niepowodzeniu?

Jesteśmy w stanie niezawodnie odtworzyć następujący scenariusz:

  1. Tworzenie małej strony HTML, która sprawia, że żądania AJAX do serwera (za pomocą HTTP POST)
  2. Odłącz się od sieci i podłącz ponownie
  3. Monitoruj Pakiety generowane przez IE po awarii

Po nieudanym połączeniu sieciowym, IE wysyła następne żądanie AJAX, ale wysyła tylko nagłówek HTTP (nie ciało) podczas wykonywania postu HTTP. Powoduje to różnego rodzaju problemy na serwerze jako to tylko częściowa Prośba. Google ten problem z Bing i znajdziesz wiele osób narzekających na "losowe błędy serwera" za pomocą AJAX lub niewyjaśnione awarie AJAX.

Wiemy, że IE (w przeciwieństwie do większości innych przeglądarek) zawsze wysyła Post HTTP jako dwa pakiety TCP / IP. Nagłówek i treść są wysyłane oddzielnie. W przypadku bezpośrednio po awarii, IE wysyła tylko nagłówek .

Moje pytanie brzmi - dlaczego tak się zachowuje? Wydaje się błędna w oparciu o specyfikację HTTP i inne przeglądarki nie zachowują się w ten sposób. Czy to tylko pluskwa? Z pewnością powoduje to spustoszenie w każdej poważnej aplikacji internetowej opartej na AJAX.

Informacje referencyjne:

Istnieje podobny problem, wywołany przez http keep-alive timeouts, które są krótsze niż 1 minuta i jest udokumentowany tutaj:

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

Oto przechwytywanie pakietów przed i po awarii:

Zauważ jak wysyłany jest nagłówek HTTP i ładunek http://img827.imageshack.us/i/beforee.png/

Po niepowodzeniu zwróć uwagę, jak wysyłany jest tylko nagłówek. IE nigdy nie wysyła payload i serwer w końcu reaguje z Timeout. http://img203.imageshack.us/i/retryt.png/

Author: Jonathon Faust, 2011-01-25

6 answers

Wydaje się, że nie ma jasnej odpowiedzi na to pytanie, więc podam moje dane empiryczne jako substytut I podam kilka sposobów obejścia tego problemu. Może jakiś ms insider kiedyś rzuci na to trochę światła...

  1. Jeśli HTTP Keep-Alive jest wyłączone na serwerze, ten problem zniknie. Innymi słowy, twój serwer HTTP 1.1 odpowie na każde żądanie Ajax za pomocą linii Connection: Close w odpowiedzi. To sprawia, że IE jest szczęśliwy, ale powoduje, że każde żądanie Ajax otwiera nowe połączenie. Może to mieć znaczący wpływ na wydajność, zwłaszcza w sieciach o dużym opóźnieniu.

  2. Problem jest łatwo wyzwalany, jeśli żądania Ajax są dokonywane w szybkim tempie. Na przykład wykonujemy żądania Ajax co 100ms, a następnie zmienia się stan sieci, błąd jest łatwy do odtworzenia. Chociaż większość aplikacji prawdopodobnie nie wysyła takich żądań, możesz mieć kilka wywołań serwerów za sobą, co może prowadzić do tego problemu. Mniej gadatliwy sprawia, że IE jest szczęśliwy.

  3. Dzieje się to nawet bez uwierzytelniania NTLM.

  4. Dzieje się tak, gdy limit czasu http keep-alive na serwerze jest krótszy niż domyślny (który domyślnie wynosi 60 sekund w systemie Windows). Szczegóły podane w odnośniku.

  5. Nie dzieje się to z Chrome lub Firefox. FF wysyła jeden pakiet więc wydaje się całkowicie uniknąć tego problemu.

  6. Dzieje się to w IE 6, 7, 8. Nie można odtworzyć z IE 9 beta.

 27
Author: Dodgyrabbit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-30 19:16:14

Artykuł microsoft KB zatytułowany Gdy używasz programu Microsoft Internet Explorer lub innego programu do wykonywania operacji ponownego posta, publikowane są tylko dane nagłówka wygląda na to, że rozwiązuje ten problem.

Artykuł zawiera poprawkę. Dla późniejszych przeglądarek, takich jak IE8 mówi, że poprawka jest już dołączona , ale musi być włączona poprzez ustawienia rejestru na komputerze klienckim.

 11
Author: Julian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-06 05:19:59

Miałem podobny problem, w którym niektóre starsze wersje IE odsyłały tylko nagłówek, a nie treść posta. Mój problem okazał się związany z IE i NTLM. Ponieważ nie wspomniałeś o NTLM, to pewnie nie pomaga, ale na wszelki wypadek:

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

 2
Author: reassembler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-27 17:34:15

To jest strzał w dziesiątkę, ale IE (a nawet Firefox) czasami " pamięta" połączenie, którego używa do żądania HTTP. Uwagi/przykłady:

  • W Firefoksie, jeśli zmienię ustawienia proxy i nacisnę SHIFT-przeładuj na strona, nadal używa starego proxy. Jeśli jednak zabiję starego proxy ("killall squid"), zaczyna używać nowego proxy.

  • Czy po odłączeniu/ponownym połączeniu otrzymasz nowy adres IP lub coś podobnego? Czy można jakoś monitorować stary adres IP zobaczyć jeśli IE wysyła dane na ten martwy adres?

  • Domyślam się, że IE wysyła dane, po prostu źle / align = "left" / Może być wystarczająco inteligentny, aby nie buforować połączeń sieciowych dla Pakiety "POST", ale może nie być wystarczająco inteligentny, aby to zrobić dla POST ładunki.

  • Prawdopodobnie nie wpływa to na większość aplikacji AJAX, ponieważ ludzie rzadko odłączyć i ponownie połączyć się z ich sieciami?

 1
Author: barrycarter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-26 17:25:46

Czy używasz uwierzytelniania NTLM?

Podczas korzystania z uwierzytelniania NTLM, IE nie wysyła danych post. Wysyła informacje o nagłówku, oczekuje nieautoryzowanej odpowiedzi wyślij autoryzację, a po "ponowne uwierzytelnienie" wysyła post.

 1
Author: The-MeLLeR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-30 14:13:21

Miałem podobny problem dzisiaj przy użyciu $.ajax i był w stanie to naprawić, ustawiając async na false.

$.ajax({
  async: false, 
  url: '[post action url]',
  data: $form.serialize(),
  type: 'POST',
  success: successCallback
});
 -1
Author: robbie kouwenberg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-25 14:41:23