Mengapa Internet Explorer tidak mengirim isi kiriman HTTP pada panggilan Ajax setelah kegagalan?

114

Kami dapat membuat ulang skenario berikut dengan andal:

  1. Buat halaman HTML kecil yang membuat permintaan AJAX ke server (menggunakan HTTP POST)
  2. Putuskan sambungan dari jaringan dan sambungkan kembali
  3. Pantau paket yang dihasilkan IE setelah kegagalan

Setelah koneksi jaringan gagal, IE membuat permintaan AJAX berikutnya tetapi hanya mengirim header HTTP (bukan isi) saat melakukan posting HTTP. Hal ini menyebabkan segala macam masalah di server karena ini hanya sebagian permintaan. Google masalah ini dengan Bing dan Anda akan menemukan banyak orang mengeluh tentang "kesalahan server acak" menggunakan AJAX atau kegagalan AJAX yang tidak dapat dijelaskan.

Kita tahu bahwa IE (tidak seperti kebanyakan browser lain) selalu mengirimkan HTTP POST sebagai DUA paket TCP / IP. Header dan body dikirim secara terpisah. Dalam kasus langsung setelah kegagalan, IE hanya mengirimkan header . IE tidak pernah mengirim payload dan server akhirnya merespons dengan Timeout.

Jadi pertanyaan saya adalah - mengapa ia berperilaku seperti ini? Tampaknya salah berdasarkan spesifikasi HTTP dan browser lain tidak berperilaku seperti ini. Apakah ini hanya bug? Tentunya ini menciptakan malapetaka dalam aplikasi Web berbasis AJAX yang serius.

Informasi referensi:

Ada masalah serupa, yang dipicu oleh waktu tunggu tetap-hidup HTTP yang kurang dari 1 menit dan didokumentasikan di sini:

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
sumber
6
Ini adalah pertanyaan yang sangat bagus dan terdefinisi dengan baik yang patut dijawab. Sayangnya, ini sedikit keluar dari topik. Saya tidak yakin apakah akan lebih baik di webmasters.stackexchange.com atau superuser.stackexchange.com .
Stephen
3
@ gilly3, saya pikir pasti ada yang salah dengan saya, karena saya membaca itu dan hanya mengangguk-angguk ...
Ryley
1
@ gilly3: bila diterjemahkan ke dalam bahasa Belanda, ini benar, karena 'googelen' adalah kata kerja (bahkan didefinisikan dalam kamus Belanda) yang berarti 'mencari web' dalam bahasa Belanda. Ya, ini dieja 'googelen' dan bukan 'googlen'. Aneh, saya tahu. Jadi, Anda bisa mengatakan: 'Googel dit probleem bertemu Bing.' dan itu akan benar.
11
@ gilly3: Bing itu apa? Aku akan Google itu.
Roket Hazmat
5
"mengapa berperilaku seperti ini?" - apakah Anda menerima jawaban "Orang Microsoft, meskipun sebagian besar brilian, adalah bagian dari budaya pemrograman yang secara fundamental berbeda dari kita yang datang ke era digital melalui DEC, Unix, Apple, Commodore, atau latar belakang lainnya, dan cenderung melakukan hal-hal yang membuat kita semua terkesiap heran, bukan pada kecemerlangan mereka, tetapi pada kerumitan mereka yang berlebihan dan kerusakan total pada hal-hal yang sederhana dan langsung bagi kita semua "?
jcomeau_ictx

Jawaban:

28

Sepertinya tidak ada jawaban yang jelas untuk pertanyaan ini, jadi saya akan memberikan data empiris saya sebagai pengganti dan memberikan beberapa cara untuk mengatasinya. Mungkin beberapa orang dalam MS suatu hari akan menjelaskan hal ini ...

  1. Jika HTTP Keep-Alive dinonaktifkan di server, masalah ini akan hilang. Dengan kata lain, server HTTP 1.1 Anda akan menanggapi setiap permintaan Ajax dengan satu Connection: Closebaris sebagai tanggapan. Ini membuat IE senang tetapi menyebabkan setiap permintaan Ajax membuka koneksi baru. Ini dapat berdampak signifikan pada kinerja, terutama pada jaringan latensi tinggi.

  2. Masalah dipicu dengan mudah jika permintaan Ajax dibuat secara berurutan dengan cepat. Misalnya, kami membuat permintaan Ajax setiap 100 md dan kemudian status jaringan berubah, kesalahan mudah direproduksi. Meskipun sebagian besar aplikasi mungkin tidak membuat permintaan seperti itu, Anda mungkin mengalami beberapa panggilan server yang terjadi tepat setelah satu sama lain yang dapat menyebabkan masalah ini. Sedikit cerewet membuat IE senang.

  3. Itu terjadi bahkan tanpa otentikasi NTLM.

  4. Itu terjadi ketika waktu tunggu tetap-hidup HTTP Anda di server lebih pendek dari default (yang default ke 60 detik di Windows). Detail tersedia di tautan yang dipermasalahkan.

  5. Ini tidak terjadi dengan Chrome atau Firefox. FF mengirimkan satu paket jadi sepertinya untuk menghindari masalah ini sama sekali.

  6. Itu terjadi di IE 6, 7, 8. Tidak dapat mereproduksi dengan IE 9 beta.

Dodgyrabbit
sumber
4
Apakah ada cara lain untuk mengatasi masalah ini? Ada perbaikan javascript? Saya mencoba melihat berbagai objek XMLHTTP dan mereka masih tidak memperbaiki masalah.
Berlin Brown
11

Artikel microsoft KB berjudul Ketika Anda menggunakan Microsoft Internet Explorer atau program lain untuk melakukan operasi POST ulang, hanya data header yang diposting tampaknya dapat memperbaiki masalah ini.

Artikel ini menyediakan perbaikan terbaru. Untuk browser yang lebih baru seperti IE8 dikatakan hotfix sudah disertakan tetapi perlu diaktifkan melalui pengaturan registri pada PC klien.

Julian
sumber
1
Saya mengalami masalah ini dengan IE10, yang tidak disebutkan dalam artikel.
ClearCloud8
6
Artikel tersebut sekarang menyebutkan hingga IE11, jadi sepertinya hal ini tidak pernah diperbaiki.
peater
Saya yakin saya mengalami masalah ini di situs produksi - agen pengguna yang terkait dengan masalah tersebut sesuai dengan IE 8,9,10 dan 11.
millhouse
Adakah yang menemukan solusi? Secara khusus saya mengirim 307 dan FF, Chrome, Safari mengirim ulang data ke titik akhir baru - IE tidak. Saya tidak bisa meminta pengguna saya untuk memperbaiki / memperbaiki registri.
Brad Gunn
2

Saya memiliki masalah serupa di mana beberapa versi IE yang lebih lama hanya akan mengirim kembali Header dan bukan badan POST. Masalah saya ternyata terkait dengan IE dan NTLM. Karena Anda tidak menyebutkan NTLM, ini mungkin tidak membantu, tetapi untuk berjaga-jaga:

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

reassembler
sumber
Tautan Anda sangat membantu dalam memecahkan masalah serupa di IE 11 dan IIS 6.
Harminder
1

Ini adalah longshot, tetapi IE (dan bahkan Firefox) terkadang "mengingat" koneksi yang digunakannya untuk permintaan HTTP. Catatan / contoh:

  • Di Firefox, jika saya mengubah pengaturan proxy dan menekan SHIFT-RELOAD pada halaman, itu masih menggunakan proxy lama. Namun, jika saya mematikan proxy lama ("killall squid"), itu mulai menggunakan proxy baru.

  • Saat Anda memutuskan / menyambungkan kembali, apakah Anda menerima alamat IP baru atau yang serupa? Dapatkah Anda memonitor alamat IP lama untuk melihat apakah IE mengirimkan data ke alamat yang sekarang sudah mati itu?

  • Dugaan saya adalah bahwa IE mengirimkan data, di jalur yang salah. Mungkin cukup pintar untuk tidak menyimpan koneksi jaringan ke cache untuk paket "POST", tetapi mungkin tidak cukup pintar untuk melakukannya untuk payload POST.

  • Ini mungkin tidak memengaruhi sebagian besar aplikasi AJAX, karena orang jarang memutuskan dan menyambungkan kembali jaringan mereka?


sumber
2
Saya pikir masalahnya adalah yang terakhir. Saya pikir Microsoft menggunakan "jarang terjadi: jangan implementasikan" -policy. :)
1
Saya memantau semua lalu lintas HTTP dari sumber ke tujuan. Saya dapat mengonfirmasi bahwa (a) alamat IP saya tidak berubah dan (b) tidak ada upaya untuk mengirim apa pun. IE membuka soket baru dan mengirimkan permintaan parsial. Cara saya membaca artikel MS, adalah salah satu update keamanan mereka merusak IE. Kemudian mereka membuat tambalan untuk memperbaikinya. Tetapi kalau-kalau Anda ingin itu berperilaku dengan cara lama "rusak", Anda dapat menambahkan kunci registri ini. Retry_HeaderOnlyPOST_OnConnectionReset. Hanya mencoba memahami kegilaan itu.
Dodgyrabbit
Pada poin terakhir Anda: jika Anda memiliki aplikasi Ajax yang melakukan polling secara berkala, katakanlah 10 detik, kami menemukan bahwa jika dibiarkan terbuka selama beberapa jam, kesalahan ini akan selalu terjadi. Mungkin koneksi Wifi terputus atau jaringan samar - tetapi pengalaman kami masalah ini sangat nyata.
Dodgyrabbit
1

Apakah Anda menggunakan otentikasi NTLM?

Saat menggunakan otentikasi NTLM, IE tidak mengirim data pasca. Ini mengirimkan info header, mengharapkan respons yang tidak sah mengirim otorisasi, dan setelah 'otentikasi ulang' mengirim posting.

The-MeLLeR
sumber
Kami tidak menggunakan otentikasi NTLM. Terjadi dengan permintaan anonim.
Dodgyrabbit
0

Saya mengalami masalah serupa hari ini ketika menggunakan $ .ajax dan dapat memperbaikinya dengan menyetel async ke false.

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

robbie kouwenberg
sumber