Internet Explorer neden başarısızlıktan sonra Ajax çağrısında HTTP gönderi gövdesi göndermiyor?


114

Aşağıdaki senaryoyu güvenilir bir şekilde yeniden oluşturabiliyoruz:

  1. Bir sunucuya AJAX istekleri gönderen küçük bir HTML sayfası oluşturun (HTTP POST kullanarak)
  2. Ağ bağlantısını kesin ve yeniden bağlanın
  3. Hatadan sonra IE'nin oluşturduğu paketleri izleyin

Başarısız bir ağ bağlantısından sonra, IE sonraki AJAX isteğini yapar, ancak HTTP gönderirken yalnızca HTTP başlığını (gövdeyi değil) gönderir. Bu, yalnızca kısmi bir istek olduğu için sunucuda her türlü soruna neden olur. Google bu sorunu Bing ile yaptığınızda, AJAX kullanan veya açıklanamayan AJAX hatalarını kullanan "rastgele sunucu hatalarından" şikayet eden birçok kişi bulacaksınız.

IE'nin (diğer tarayıcıların çoğunun aksine) her zaman İKİ TCP / IP paketi olarak bir HTTP POST'u gönderdiğini biliyoruz. Başlık ve gövde ayrı olarak gönderilir. Bir hatanın hemen ardından oluşan durumda, IE yalnızca başlığı gönderir . IE hiçbir zaman yükü göndermez ve sunucu sonunda bir Zaman Aşımı ile yanıt verir.

Öyleyse sorum şu - neden bu şekilde davranıyor? HTTP spesifikasyonuna göre yanlış görünüyor ve diğer tarayıcılar bu şekilde davranmıyor. Bu sadece bir hata mı? Elbette bu, herhangi bir ciddi AJAX tabanlı Web uygulamasında hasara neden olur.

Referans bilgisi:

1 dakikadan kısa olan ve burada belgelenen HTTP canlı tutma zaman aşımları tarafından tetiklenen benzer bir sorun var:

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


6
Bu, bir cevabı hak eden mükemmel, iyi tanımlanmış bir sorudur. Ne yazık ki bu biraz konu dışı. Webmasters.stackexchange.com veya superuser.stackexchange.com'da daha iyi olur muydu emin değilim .
Stephen

3
@ gilly3, bende bir sorun olduğunu düşünüyorum, çünkü bunu okudum ve sadece başımı sallıyordum ...
Ryley

1
@ gilly3: Hollandaca'ya çevrildiğinde bu doğru olacaktır, çünkü 'googelen' Hollandaca'da 'web'de arama yapmak' anlamına gelen bir fiildir (Hollandaca sözlükte tanımlanmıştır). Evet, "googelen" değil, "googelen" olarak yazılır. Garip, biliyorum. Yani, "Googel dit probleem, Bing ile karşılaştı" diyebilirsiniz. ve doğru olacaktır.

11
@ gilly3: Bing nedir? Google yapacağım.
Rocket Hazmat

5
"neden bu şekilde davranıyor?" - bir yanıt olarak kabul eder miydiniz? "Microsoft çalışanları, çoğunlukla mükemmel olsa da, DEC, Unix, Apple, Commodore veya diğer geçmişlerle dijital çağa giren bizden temelde farklı bir programlama kültürünün parçası. ve geri kalanımızı şaşkınlık içinde yutturan şeyler yapma eğilimindeyiz, parlaklıkları karşısında değil, geri kalanımız için basit ve anlaşılır olan şeylerin aşırı karmaşıklığı ve tamamen yozlaşması nedeniyle "?
jcomeau_ictx

Yanıtlar:


28

Bu soruya net bir cevap yok gibi görünüyor, bu yüzden deneysel verilerimi bir ikame olarak sunacağım ve bunun etrafında çalışmak için bazı yollar sunacağım. Belki MS içerisindeki bazı kişiler bir gün buna ışık tutacaktır ...

  1. Sunucuda HTTP Canlı Tutun devre dışı bırakılırsa , bu sorun ortadan kalkar. Diğer bir deyişle, HTTP 1.1 sunucunuz her Ajax isteğine Connection: Closeyanıtta bir satır ile yanıt verecektir . Bu, IE'yi mutlu eder ancak her Ajax isteğinin yeni bir bağlantı açmasına neden olur. Bunun, özellikle yüksek gecikmeli ağlarda önemli bir performans etkisi olabilir.

  2. Ajax istekleri arka arkaya hızlı bir şekilde yapılırsa sorun kolayca tetiklenir. Örneğin, her 100 ms'de Ajax istekleri yapıyoruz ve ardından ağ durumu değişiyor, hatanın yeniden oluşturulması kolaydır. Çoğu uygulama muhtemelen bu tür isteklerde bulunmasa da, birbirinin hemen ardından gelen ve bu soruna yol açabilecek birkaç sunucu çağrınız olabilir. Daha az konuşma IE'yi mutlu eder.

  3. NTLM kimlik doğrulaması olmadan bile gerçekleşir.

  4. Sunucudaki HTTP canlı tutma zaman aşımınız varsayılandan daha kısa olduğunda (Windows'ta varsayılan olarak 60 saniyedir) gerçekleşir. Söz konusu bağlantıda verilen ayrıntılar.

  5. Chrome veya Firefox'ta olmaz. FF bir paket gönderdiği için bu sorunu tamamen önlediği görülüyor.

  6. IE 6, 7, 8'de oluyor. IE 9 beta ile çoğaltılamıyor.


4
Bu sorunu çözmenin başka yolları var mı? Herhangi bir javascript düzeltmesi var mı? Çeşitli XMLHTTP nesnelerine bakmayı denedim ve yine de sorunu çözmediler.
Berlin Brown

11

Yeniden POST işlemi gerçekleştirmek için Microsoft Internet Explorer veya başka bir program kullandığınızda, yalnızca başlık verilerinin gönderildiği başlıklı Microsoft KB makalesi bu sorunu gideriyor gibi görünüyor.

Makale bir düzeltme sağlar. IE8 gibi daha sonraki tarayıcılar için, düzeltmenin zaten dahil edildiğini ancak istemci bilgisayardaki kayıt defteri ayarlarından etkinleştirilmesi gerektiğini söylüyor .


1
Makalede bahsetmeyen IE10 ile bu sorunu yaşıyorum.
ClearCloud8

6
Makale şimdi IE11'e kadar bahsediyor, bu yüzden bu asla düzeltilmemiş gibi görünüyor.
peater

Bu sorunu bir üretim sitesinde yaşadığıma inanıyorum - sorunla ilişkili kullanıcı aracıları IE 8,9,10 ve 11'e karşılık geliyor
millhouse

Bir geçici çözüm bulan var mı? Özellikle bir 307 ve FF, Chrome, Safari gönderiyorum verileri yeni uç noktaya yeniden gönderiyorum - IE değil. Kullanıcılarımdan düzeltme / kayıt düzeltme eki isteyemiyorum.
Brad Gunn

2

IE'nin bazı eski sürümlerinin bir POST'un gövdesini değil, yalnızca Başlığı geri gönderdiği benzer bir sorun yaşadım. Sorunumun IE ve NTLM ile ilgili olduğu ortaya çıktı. NTLM'den bahsetmediğiniz için, bu muhtemelen yardımcı olmuyor, ancak her ihtimale karşı:

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


Bağlantınız IE 11 ve IIS 6'daki benzer problemleri çözmede yardımcı oldu.
Harminder

1

Bu uzun bir görüntüdür, ancak IE (ve hatta Firefox) bazen bir HTTP isteği için kullandığı bağlantıyı "hatırlar". Notlar / örnekler:

  • Firefox'ta, proxy ayarlarını değiştirirsem ve bir sayfada SHIFT-RELOAD'a basarsam, hala eski proxy'yi kullanıyor. Ancak, eski proxy'yi ("killall squid") öldürürsem, yeni proxy'yi kullanmaya başlar.

  • Bağlantıyı kestiğinizde / yeniden bağlandığınızda, yeni bir IP adresi veya benzeri bir şey alıyor musunuz? IE'nin bu ölü adrese veri gönderip göndermediğini görmek için eski IP adresini bir şekilde izleyebilir misiniz?

  • Tahminimce, IE verileri yanlış yoldan gönderiyor. "POST" paketleri için ağ bağlantılarını önbelleğe almamak yeterince akıllı olabilir, ancak POST yükleri için bunu yapacak kadar akıllı olmayabilir.

  • Bu muhtemelen çoğu AJAX uygulamasını etkilemiyor, çünkü insanlar nadiren bağlantılarını kesip ağlarına yeniden bağlanıyorlar mı?


2
Sanırım sorun sonuncu. Sanırım Microsoft, "nadiren olur: uygulama" -politikasını kullanır. :)

1
Kaynaktan hedefe tüm HTTP trafiğini izliyorum. (A) IP adresimin değişmediğini ve (b) başka bir şey gönderme girişiminin olmadığını doğrulayabilirim. IE yeni bir yuva açar ve kısmi bir istek gönderir. MS makalesini okuma şeklim, güvenlik güncellemelerinden biri IE'yi kırdı. Sonra bunu düzeltmek için bir yama oluşturdular. Ancak eski "bozuk" şekilde davranmasını istemeniz durumunda, bu kayıt defteri anahtarını ekleyebilirsiniz. Retry_HeaderOnlyPOST_OnConnectionReset. Sadece çılgınlığı anlamaya çalışıyorum.
Dodgyrabbit

Son olarak: periyodik olarak anket yapan bir Ajax uygulamanız varsa, örneğin 10 saniye, birkaç saat açık bırakılırsa bu hatanın her zaman gerçekleşeceğini görürüz. Muhtemelen ağdan düşen veya yarım yamalak ağ yapan Wifi bağlantısı - ancak deneyimlerimiz bu sorun çok gerçektir.
Dodgyrabbit

1

NTLM kimlik doğrulaması kullanıyor musunuz?

NTLM kimlik doğrulamasını kullanırken, IE sonradan veri göndermez. Başlık bilgilerini gönderir, yetkisiz bir yanıtın yetkilendirme göndermesini bekler ve 'yeniden kimlik doğrulama' gönderiyi gönderdikten sonra.


NTLM kimlik doğrulaması kullanmıyoruz. İsimsiz isteklerde olur.
Dodgyrabbit

0

Bugün $ .ajax kullanırken benzer bir sorun yaşadım ve async'i false olarak ayarlayarak düzeltebildim.

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.