เหตุใด Internet Explorer จึงไม่ส่งเนื้อหาโพสต์ HTTP ในการโทร Ajax หลังจากล้มเหลว


114

เราสามารถสร้างสถานการณ์ต่อไปนี้ขึ้นใหม่ได้อย่างน่าเชื่อถือ:

  1. สร้างเพจ HTML ขนาดเล็กที่ส่งคำขอ AJAX ไปยังเซิร์ฟเวอร์ (โดยใช้ HTTP POST)
  2. ยกเลิกการเชื่อมต่อจากเครือข่ายและเชื่อมต่อใหม่
  3. ตรวจสอบแพ็กเก็ตที่ IE สร้างขึ้นหลังจากความล้มเหลว

หลังจากการเชื่อมต่อเครือข่ายล้มเหลว IE จะส่งคำขอ AJAX ถัดไป แต่จะส่งเฉพาะส่วนหัว HTTP (ไม่ใช่เนื้อหา) เมื่อทำการโพสต์ HTTP สิ่งนี้ทำให้เกิดปัญหาทุกประเภทบนเซิร์ฟเวอร์เนื่องจากเป็นเพียงคำขอบางส่วน Google พบปัญหานี้กับ Bing และคุณจะพบผู้คนจำนวนมากบ่นเกี่ยวกับ "ข้อผิดพลาดของเซิร์ฟเวอร์แบบสุ่ม" โดยใช้ AJAX หรือความล้มเหลวของ AJAX ที่ไม่ได้อธิบาย

เราทราบดีว่า IE (ไม่เหมือนกับเบราว์เซอร์อื่น ๆ ส่วนใหญ่) จะส่ง HTTP POST เป็นสองแพ็กเก็ต TCP / IP เสมอ ส่วนหัวและเนื้อหาจะถูกส่งแยกกัน ในกรณีที่เกิดความล้มเหลวโดยตรงIE จะส่งเฉพาะส่วนหัวเท่านั้น IE ไม่เคยส่ง payload และในที่สุดเซิร์ฟเวอร์ก็ตอบสนองด้วย Timeout

คำถามของฉันคือ - ทำไมมันถึงทำงานแบบนี้? ดูเหมือนว่าผิดตามข้อมูลจำเพาะ HTTP และเบราว์เซอร์อื่น ๆ ไม่ทำงานในลักษณะนี้ มันเป็นเพียงข้อผิดพลาดหรือไม่? แน่นอนว่าสิ่งนี้สร้างความเสียหายในแอปพลิเคชันเว็บที่ใช้ AJAX อย่างร้ายแรง

ข้อมูลอ้างอิง:

มีปัญหาที่คล้ายกันซึ่งเกิดจากการหมดเวลาของ HTTP ที่มีชีวิตอยู่ซึ่งสั้นกว่า 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


6
นี่เป็นคำถามที่ยอดเยี่ยมและกำหนดไว้อย่างดีซึ่งสมควรได้รับคำตอบ น่าเสียดายที่นี่เป็นหัวข้อเล็กน้อย ผมไม่แน่ใจว่ามันจะดีขึ้นในwebmasters.stackexchange.comหรือsuperuser.stackexchange.com
Stephen

3
@ gilly3 ฉันคิดว่าต้องมีบางอย่างผิดปกติกับฉันเพราะฉันอ่านแล้วและก็พยักหน้าตาม ...
Ryley

1
@ gilly3: เมื่อแปลเป็นภาษาดัตช์สิ่งนี้จะถูกต้องเนื่องจาก 'googelen' เป็นคำกริยา (กำหนดไว้ในพจนานุกรมภาษาดัตช์) หมายถึง 'การค้นหาเว็บ' ในภาษาดัตช์ ใช่มันสะกดว่า 'googelen' ไม่ใช่ 'googlen' แปลกฉันรู้ คุณสามารถพูดได้ว่า: 'Googel dit Solution met Bing' และมันจะถูกต้อง

11
@ gilly3: Bing คืออะไร? ฉันจะใช้ Google
Rocket Hazmat

5
“ ทำไมมันถึงทำตัวแบบนี้” - คุณจะยอมรับคำตอบหรือไม่ "คน Microsoft แม้ว่าส่วนใหญ่จะเป็นคนเก่ง แต่ก็เป็นส่วนหนึ่งของวัฒนธรรมการเขียนโปรแกรมที่แตกต่างไปจากพวกเราที่เข้ามาในยุคดิจิทัลผ่าน DEC, Unix, Apple, Commodore หรือภูมิหลังอื่น ๆ และมีแนวโน้มที่จะทำในสิ่งที่ทำให้พวกเราที่เหลืออ้าปากค้างด้วยความประหลาดใจไม่ใช่ด้วยความฉลาดของพวกเขา แต่เป็นความซับซ้อนและความเสียหายทั้งหมดของสิ่งที่เรียบง่ายและตรงไปตรงมาสำหรับพวกเราที่เหลือ "?
jcomeau_ictx

คำตอบ:


28

ดูเหมือนจะไม่มีคำตอบที่ชัดเจนสำหรับคำถามนี้ดังนั้นฉันจะให้ข้อมูลเชิงประจักษ์เป็นข้อมูลทดแทนและให้วิธีการบางอย่างในการแก้ไข บางทีคนวงใน MS บางคนอาจจะให้ความกระจ่างในเรื่องนี้ ...

  1. หาก HTTP Keep-Alive ถูกปิดใช้งานบนเซิร์ฟเวอร์ปัญหานี้จะหายไป กล่าวอีกนัยหนึ่งเซิร์ฟเวอร์ HTTP 1.1 ของคุณจะตอบสนองทุกคำขอของ Ajax พร้อมกับConnection: Closeบรรทัดในการตอบกลับ สิ่งนี้ทำให้ IE มีความสุข แต่ทำให้ทุกคำขอ Ajax เปิดการเชื่อมต่อใหม่ ซึ่งอาจส่งผลกระทบต่อประสิทธิภาพอย่างมากโดยเฉพาะในเครือข่ายที่มีเวลาแฝงสูง

  2. ปัญหานี้จะเกิดขึ้นได้อย่างง่ายดายหากมีการร้องขอ Ajax ติดต่อกันอย่างรวดเร็ว ตัวอย่างเช่นเราทำการร้องขอ Ajax ทุกๆ 100ms จากนั้นสถานะเครือข่ายจะเปลี่ยนไปข้อผิดพลาดนั้นเกิดขึ้นได้ง่าย แม้ว่าแอปพลิเคชันส่วนใหญ่อาจไม่ได้ทำการร้องขอดังกล่าว แต่คุณอาจมีการเรียกเซิร์ฟเวอร์สองสามสายที่เกิดขึ้นพร้อมกันซึ่งอาจทำให้เกิดปัญหานี้ได้ ช่างพูดน้อยทำให้ IE มีความสุข

  3. เกิดขึ้นได้แม้ไม่มีการตรวจสอบสิทธิ์ NTLM

  4. จะเกิดขึ้นเมื่อการหมดเวลาใช้งาน HTTP ของคุณบนเซิร์ฟเวอร์สั้นกว่าค่าเริ่มต้น (ซึ่งค่าเริ่มต้นคือ 60 วินาทีใน Windows) รายละเอียดอยู่ในลิงค์ที่มีปัญหา

  5. ไม่เกิดขึ้นกับ Chrome หรือ Firefox FF ส่งหนึ่งแพ็คเก็ตเพื่อหลีกเลี่ยงปัญหานี้โดยสิ้นเชิง

  6. มันเกิดขึ้นใน IE 6, 7, 8 ไม่สามารถทำซ้ำกับ IE 9 เบต้าได้


4
มีวิธีอื่นในการแก้ไขปัญหานี้หรือไม่? แก้ไขจาวาสคริปต์หรือไม่ ฉันลองดูวัตถุ XMLHTTP ต่างๆแล้ว แต่ก็ยังไม่สามารถแก้ไขปัญหาได้
Berlin Brown

11

บทความ microsoft KB ที่มีชื่อว่าเมื่อคุณใช้ Microsoft Internet Explorer หรือโปรแกรมอื่นในการดำเนินการโพสต์ซ้ำจะมีการโพสต์เฉพาะข้อมูลส่วนหัวเท่านั้นที่จะแก้ไขปัญหานี้ได้

บทความนี้มีโปรแกรมแก้ไขด่วน สำหรับเบราว์เซอร์รุ่นหลังเช่น IE8 ระบุว่ามีโปรแกรมแก้ไขด่วนอยู่แล้วแต่ต้องเปิดใช้งานผ่านการตั้งค่ารีจิสทรีบนพีซีไคลเอนต์


1
ฉันกำลังประสบปัญหานี้กับ IE10 ซึ่งบทความไม่ได้กล่าวถึง
ClearCloud8

6
ตอนนี้บทความกล่าวถึง IE11 ดังนั้นดูเหมือนว่าจะไม่ได้รับการแก้ไข
peater

ฉันเชื่อว่าฉันกำลังประสบปัญหานี้ในไซต์การผลิต - ตัวแทนผู้ใช้ที่เกี่ยวข้องกับปัญหานี้สอดคล้องกับ IE 8,9,10 และ 11
millhouse

มีใครพบวิธีแก้ปัญหาหรือไม่? โดยเฉพาะอย่างยิ่งฉันส่ง 307 และ FF, Chrome, Safari repost ข้อมูลไปยังจุดสิ้นสุดใหม่ - IE ไม่ทำ ฉันไม่สามารถขอให้ผู้ใช้แก้ไขโปรแกรมแก้ไขด่วน / รีจิสทรีได้
Brad Gunn

2

ฉันมีปัญหาคล้ายกันซึ่ง IE เวอร์ชันเก่าบางรุ่นจะส่งกลับเฉพาะส่วนหัวเท่านั้นไม่ใช่เนื้อหาของ POST ปัญหาของฉันเกี่ยวข้องกับ IE และ NTLM เนื่องจากคุณไม่ได้พูดถึง NTLM สิ่งนี้อาจไม่ได้ช่วย แต่ในกรณี:

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


ลิงก์ของคุณมีประโยชน์ในการแก้ปัญหาที่คล้ายกันใน IE 11 และ IIS 6
Harminder

1

นี่เป็นภาพระยะสั้น แต่ IE (และแม้แต่ Firefox) บางครั้งก็ "จำ" การเชื่อมต่อที่ใช้สำหรับคำขอ HTTP Notes / ตัวอย่าง:

  • ใน Firefox ถ้าฉันเปลี่ยนการตั้งค่าพร็อกซีและกด SHIFT-RELOAD บนเพจมันยังคงใช้พร็อกซีแบบเก่า อย่างไรก็ตามถ้าฉันฆ่าพร็อกซีเก่า ("killall Squid") มันจะเริ่มใช้พร็อกซีใหม่

  • เมื่อคุณยกเลิกการเชื่อมต่อ / เชื่อมต่อใหม่คุณได้รับที่อยู่ IP ใหม่หรืออะไรที่คล้ายกันหรือไม่? คุณสามารถตรวจสอบที่อยู่ IP เก่าได้หรือไม่เพื่อดูว่า IE กำลังส่งข้อมูลไปยังที่อยู่ที่ตายแล้วหรือไม่?

  • ฉันเดาว่า IE กำลังส่งข้อมูลเพียงแค่ลงผิดเส้นทาง อาจเป็นการฉลาดพอที่จะไม่แคชการเชื่อมต่อเครือข่ายสำหรับแพ็กเก็ต "POST" แต่อาจไม่ฉลาดพอที่จะทำเช่นนั้นสำหรับเพย์โหลด POST

  • สิ่งนี้อาจไม่ส่งผลกระทบต่อแอป AJAX ส่วนใหญ่เนื่องจากผู้คนไม่ค่อยตัดการเชื่อมต่อและเชื่อมต่อกับเครือข่ายอีกครั้ง?


2
ผมคิดว่าปัญหาคือข้อสุดท้าย ฉันคิดว่า Microsoft ใช้ -policy แบบ "ไม่ค่อยเกิดขึ้น: อย่าใช้" :)

1
ฉันตรวจสอบการรับส่งข้อมูล HTTP ทั้งหมดจากต้นทางไปยังปลายทาง ฉันสามารถยืนยันได้ว่า (ก) ที่อยู่ IP ของฉันไม่ได้เปลี่ยนแปลงและ (b) ไม่มีความพยายามที่จะส่งสิ่งอื่นใด IE เปิดซ็อกเก็ตใหม่และส่งคำขอบางส่วน วิธีที่ฉันอ่านบทความ MS เป็นหนึ่งในการอัปเดตความปลอดภัยของพวกเขาที่ทำให้ IE เสียหาย จากนั้นพวกเขาสร้างแพทช์เพื่อแก้ไขปัญหานั้น แต่ในกรณีที่คุณต้องการให้ทำงานในลักษณะ "เสีย" แบบเก่าคุณสามารถเพิ่มคีย์รีจิสทรีนี้ได้ Retry_HeaderOnlyPOST_OnConnectionReset แค่พยายามทำให้รู้สึกถึงความบ้าคลั่ง
Dodgyrabbit

ในประเด็นสุดท้ายของคุณ: หากคุณมีแอป Ajax ที่ทำการสำรวจเป็นระยะโดยพูดว่า 10 วินาทีเราพบว่าหากเปิดทิ้งไว้สองสามชั่วโมงข้อผิดพลาดนี้จะเกิดขึ้นอย่างสม่ำเสมอ อาจเป็นการเชื่อมต่อ Wifi ที่หลุดหรือเครือข่ายไม่สมบูรณ์ - แต่ประสบการณ์ของเราปัญหานี้เป็นเรื่องจริงมาก
Dodgyrabbit

1

คุณใช้การรับรองความถูกต้อง NTLM หรือไม่

เมื่อใช้การรับรองความถูกต้อง NTLM IE จะไม่ส่งข้อมูลภายหลัง จะส่งข้อมูลส่วนหัวคาดว่าการตอบกลับโดยไม่ได้รับอนุญาตจะส่งการอนุมัติและหลังจาก 'การตรวจสอบสิทธิ์อีกครั้ง' จะส่งโพสต์


เราไม่ใช้การรับรองความถูกต้องของ NTLM เกิดขึ้นกับคำขอที่ไม่ระบุชื่อ
Dodgyrabbit

0

วันนี้ฉันมีปัญหาคล้ายกันเมื่อใช้ $ .ajax และสามารถแก้ไขได้โดยตั้งค่า async เป็นเท็จ

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.