Warum sendet Internet Explorer nach einem Fehler keinen HTTP-Post-Body beim Ajax-Aufruf?

114

Wir können das folgende Szenario zuverlässig neu erstellen:

  1. Erstellen Sie eine kleine HTML-Seite, die AJAX-Anforderungen an einen Server sendet (mithilfe von HTTP POST).
  2. Trennen Sie die Verbindung zum Netzwerk und stellen Sie die Verbindung wieder her
  3. Überwachen Sie die Pakete, die der IE nach dem Fehler generiert

Nach einer fehlgeschlagenen Netzwerkverbindung stellt der IE die nächste AJAX-Anforderung, sendet jedoch nur den HTTP-Header (nicht den Body), wenn der HTTP-Beitrag ausgeführt wird. Dies verursacht alle möglichen Probleme auf dem Server, da es sich nur um eine Teilanforderung handelt. Google dieses Problem mit Bing und Sie werden viele Leute finden, die sich über "zufällige Serverfehler" mit AJAX oder ungeklärte AJAX-Fehler beschweren.

Wir wissen, dass der IE (im Gegensatz zu den meisten anderen Browsern) einen HTTP-POST immer als ZWEI TCP / IP-Pakete sendet. Der Header und der Body werden separat gesendet. Im Fall direkt nach einem Fehler sendet der IE nur den Header . IE sendet niemals die Nutzdaten und der Server antwortet schließlich mit einem Timeout.

Meine Frage ist also - warum verhält es sich so? Aufgrund der HTTP-Spezifikation scheint dies falsch zu sein, und andere Browser verhalten sich nicht so. Ist es einfach ein Fehler? Dies führt sicherlich zu Chaos in jeder ernsthaften AJAX-basierten Webanwendung.

Referenzinformationen:

Es gibt ein ähnliches Problem, das durch HTTP-Keep-Alive-Timeouts ausgelöst wird, die kürzer als 1 Minute sind und hier dokumentiert sind:

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

Dodgyrabbit
quelle
6
Dies ist eine ausgezeichnete, genau definierte Frage, die eine Antwort verdient. Leider ist dies ein wenig abseits des Themas. Ich bin mir nicht sicher, ob es auf webmasters.stackexchange.com oder superuser.stackexchange.com besser wäre .
Stephen
3
@ gilly3, ich denke, etwas muss mit mir nicht stimmen, weil ich das gelesen habe und nur mitnickte ...
Ryley
1
@ gilly3: Wenn es ins Niederländische übersetzt wird, wäre dies korrekt, da 'googelen' ein Verb (sogar im niederländischen Wörterbuch definiert) ist, das auf Niederländisch 'im Web suchen' bedeutet. Ja, es heißt "googelen" und nicht "googlen". Seltsam, ich weiß. Man könnte also einfach sagen: "Googel dit probleem traf Bing." und es wäre richtig.
11
@ gilly3: Was ist Bing? Ich werde es googeln.
Rocket Hazmat
5
"Warum verhält es sich so?" - Würden Sie eine Antwort akzeptieren? "Microsoft-Mitarbeiter sind zwar größtenteils brillant, aber Teil einer Programmierkultur, die sich grundlegend von denen von uns unterscheidet, die durch DEC, Unix, Apple, Commodore oder andere Hintergründe in das digitale Zeitalter eingetreten sind." und dazu neigen, Dinge zu tun, die den Rest von uns vor Staunen nach Luft schnappen lassen, nicht wegen ihrer Brillanz, sondern wegen ihrer Überkomplikation und völligen Verfälschung von Dingen, die für den Rest von uns einfach und unkompliziert sind "?
jcomeau_ictx

Antworten:

28

Es scheint keine klare Antwort auf diese Frage zu geben, daher werde ich meine empirischen Daten als Ersatz bereitstellen und einige Möglichkeiten zur Umgehung dieser Probleme bereitstellen. Vielleicht wird eines Tages ein MS-Insider etwas Licht ins Dunkel bringen ...

  1. Wenn HTTP Keep-Alive auf dem Server deaktiviert ist , wird dieses Problem behoben. Mit anderen Worten, Ihr HTTP 1.1-Server antwortet auf jede Ajax-Anfrage mit einer Connection: CloseZeile in der Antwort. Dies macht den IE glücklich, führt jedoch dazu, dass bei jeder Ajax-Anforderung eine neue Verbindung hergestellt wird. Dies kann erhebliche Auswirkungen auf die Leistung haben, insbesondere in Netzwerken mit hoher Latenz.

  2. Das Problem wird leicht ausgelöst, wenn Ajax-Anfragen schnell hintereinander gestellt werden. Zum Beispiel stellen wir alle 100 ms Ajax-Anfragen und dann ändert sich der Netzwerkstatus. Der Fehler ist leicht zu reproduzieren. Obwohl die meisten Anwendungen solche Anfragen wahrscheinlich nicht stellen, werden möglicherweise einige Serveraufrufe direkt nacheinander ausgeführt, was zu diesem Problem führen kann. Weniger gesprächig macht IE glücklich.

  3. Dies geschieht auch ohne NTLM-Authentifizierung.

  4. Dies tritt auf, wenn Ihr HTTP-Keep-Alive-Timeout auf dem Server kürzer als der Standard ist (unter Windows standardmäßig 60 Sekunden). Details finden Sie im betreffenden Link.

  5. Dies ist bei Chrome oder Firefox nicht der Fall. FF sendet ein Paket und scheint dieses Problem insgesamt zu vermeiden.

  6. Es passiert in IE 6, 7, 8. Konnte nicht mit IE 9 Beta reproduzieren.

Dodgyrabbit
quelle
4
Gibt es andere Möglichkeiten, um dieses Problem zu beheben? Irgendwelche Javascript-Korrekturen? Ich habe versucht, die verschiedenen XMLHTTP-Objekte zu untersuchen, aber sie haben das Problem immer noch nicht behoben.
Berlin Brown
11

Der Microsoft KB-Artikel mit dem Titel Wenn Sie Microsoft Internet Explorer oder ein anderes Programm verwenden, um einen erneuten POST-Vorgang auszuführen, scheint dieses Problem nur durch die veröffentlichten Header-Daten behoben zu werden.

Der Artikel enthält einen Hotfix. Für spätere Browser wie IE8 heißt es, dass der Hotfix bereits enthalten ist, aber über die Registrierungseinstellungen auf dem Client-PC aktiviert werden muss .

julianisch
quelle
1
Ich habe dieses Problem mit IE10, das im Artikel nicht erwähnt wird.
ClearCloud8
6
Der Artikel erwähnt jetzt bis zu IE11, so dass es so aussieht, als ob dies nie behoben wurde.
Peater
Ich glaube, ich habe dieses Problem auf einer Produktionsstätte - die mit dem Problem verbundenen Benutzeragenten entsprechen IE 8,9,10 und 11.
Millhouse
Hat jemand eine Problemumgehung gefunden? Insbesondere sende ich eine 307 und FF, Chrome, Safari reposte die Daten an den neuen Endpunkt - IE nicht. Ich kann meine Benutzer nicht zum Hotfix / Registrierungs-Patch auffordern.
Brad Gunn
2

Ich hatte ein ähnliches Problem, bei dem einige ältere Versionen des IE nur den Header und nicht den Text eines POST zurücksendeten. Es stellte sich heraus, dass mein Problem mit IE und NTLM zusammenhängt. Da Sie NTLM nicht erwähnt haben, hilft dies wahrscheinlich nicht, aber nur für den Fall:

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

wieder zusammenbauen
quelle
Ihr Link war hilfreich bei der Lösung ähnlicher Probleme in IE 11 und IIS 6.
Harminder
1

Dies ist ein Longshot, aber der IE (und sogar Firefox) "erinnert" sich manchmal an die Verbindung, die er für eine HTTP-Anforderung verwendet. Anmerkungen / Beispiele:

  • Wenn ich in Firefox die Proxy-Einstellungen ändere und auf einer Seite UMSCHALT-RELOAD drücke, wird weiterhin der alte Proxy verwendet. Wenn ich jedoch den alten Proxy ("killall squid") töte, wird der neue Proxy verwendet.

  • Erhalten Sie beim Trennen / erneuten Verbinden eine neue IP-Adresse oder ähnliches? Können Sie die alte IP-Adresse irgendwie überwachen, um festzustellen, ob der IE Daten an diese jetzt tote Adresse sendet?

  • Ich vermute, dass der IE die Daten auf dem falschen Weg sendet. Es ist möglicherweise intelligent genug, Netzwerkverbindungen nicht für "POST" -Pakete zwischenzuspeichern, aber möglicherweise nicht intelligent genug, um dies für POST-Nutzdaten zu tun.

  • Dies betrifft wahrscheinlich nicht die meisten AJAX-Apps, da Benutzer selten die Verbindung zu ihren Netzwerken trennen und erneut herstellen.


quelle
2
Ich denke, das Problem ist das letzte. Ich denke, Microsoft verwendet eine "selten passiert: nicht implementieren" -Politik. :)
1
Ich überwache den gesamten HTTP-Verkehr von der Quelle zum Ziel. Ich kann bestätigen, dass (a) sich meine IP-Adresse nicht geändert hat und (b) kein Versuch unternommen wurde, etwas anderes zu senden. IE öffnet einen neuen Socket und sendet eine Teilanforderung. Die Art und Weise, wie ich den MS-Artikel gelesen habe, ist eines ihrer Sicherheitsupdates, das den IE kaputt gemacht hat. Dann haben sie einen Patch erstellt, um das zu beheben. Aber nur für den Fall, dass Sie möchten, dass es sich wie früher "kaputt" verhält, können Sie diesen Registrierungsschlüssel hinzufügen. Retry_HeaderOnlyPOST_OnConnectionReset. Ich versuche nur, den Wahnsinn zu verstehen.
Dodgyrabbit
Zu Ihrem letzten Punkt: Wenn Sie eine Ajax-App haben, die regelmäßig abfragt, z. B. 10 Sekunden, wird dieser Fehler ausnahmslos auftreten, wenn er einige Stunden lang offen bleibt. Wahrscheinlich eine unterbrochene WLAN-Verbindung oder ein lückenhaftes Netzwerk - aber unserer Erfahrung nach ist dieses Problem sehr real.
Dodgyrabbit
1

Verwenden Sie die NTLM-Authentifizierung?

Bei Verwendung der NTLM-Authentifizierung sendet der IE keine Postdaten. Es sendet Header-Informationen, erwartet eine nicht autorisierte Antwort-Sendeberechtigung und sendet nach der erneuten Authentifizierung den Beitrag.

The-MeLLeR
quelle
Wir verwenden keine NTLM-Authentifizierung. Passiert mit anonymen Anfragen.
Dodgyrabbit
0

Ich hatte heute ein ähnliches Problem bei der Verwendung von $ .ajax und konnte es beheben, indem ich async auf false setzte.

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

Robbie Kouwenberg
quelle