Чому 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 ніколи не надсилає корисне навантаження, і сервер врешті-решт відповідає на час очікування.

Тож моє запитання - чому він поводиться так? Здається, неправильно на основі специфікації HTTP та інші веб-переглядачі не ведуть себе таким чином. Це просто помилка? Звичайно, це створює хаос у будь-яких серйозних веб-додатках на базі AJAX.

Довідкова інформація:

Існує аналогічна проблема, викликана тимчасовими таймаутами зберігання HTTP, які тривають менше 1 хвилини, і тут задокументовано:

http://us.generation-nt.com/xmlhttprequest-post-somasures-fails-when-server-using-keep-aliv-help-188813541.html

http://support.microsoft.com/default.aspx?kbid=831167


6
Це відмінне, чітко визначене питання, яке заслуговує на відповідь. На жаль, це трохи поза темою. Я не впевнений, чи буде це краще на webmasters.stackexchange.com або superuser.stackexchange.com .
Стівен

3
@ gilly3, я думаю, що щось зі мною має бути не так, тому що я прочитав це і просто кивнув разом ...
Ryley

1
@ gilly3: при перекладі на голландську це було б правильно, так як 'googelen' - це дієслово (навіть визначене в голландському словнику), що означає «шукати в Інтернеті» голландською мовою. Так, це написано "googelen", а не "googlen". Як це не дивно, я знаю. Отже, ви можете просто сказати: "Googel dit probleem met Bing". і це було б правильно.

11
@ gilly3: Що Bing? Я збираюся Google це.
Ракета Hazmat

5
"чому він поводиться так?" - Чи приймете ви відповідь: "Майкрософт, хоча здебільшого геніальний, є частиною культури програмування, принципово відмінною від нас із тих, хто потрапив у цифрову епоху через DEC, Unix, Apple, Commodore чи інший досвід", і схильні робити те, що змушує решти нас дивуватися не в їхньому блиску, а в їх надмірному ускладненні та тотальній зіпсованості речей, простих і очевидних для всіх нас "?
jcomeau_ictx

Відповіді:


28

На це питання, здається, немає чіткої відповіді, тому я надам свої емпіричні дані в якості замінника та запропоную деякі способи подолати це. Можливо, якийсь інсайдер-міністр одного разу проллє світло на це ...

  1. Якщо HTTP Keep-Alive відключений на сервері, ця проблема вимикається. Іншими словами, ваш сервер HTTP 1.1 відповість на кожен запит Ajax Connection: Closeрядком у відповіді. Це підтримує IE щасливим, але викликає кожне прохання Ajax відкрити нове з'єднання. Це може мати значний вплив на продуктивність, особливо в мережах з високою затримкою.

  2. Проблема викликається легко, якщо запити Ajax зроблені швидко. Наприклад, ми робимо запити Ajax кожні 100 мс, а потім статус мережі змінюється, помилка легко відтворити. Незважаючи на те, що більшість додатків, ймовірно, не роблять таких запитів, у вас може виникнути декілька викликів серверів, що відбуваються відразу один за одним, що може призвести до цієї проблеми. Менше балаканини підтримує IE щасливим.

  3. Це відбувається навіть без аутентифікації NTLM.

  4. Це трапляється, коли очікуваний час зберігання HTTP-режиму на сервері коротший за замовчуванням (який за замовчуванням становить 60 секунд у Windows). Деталі надаються за посиланням, про яке йдеться.

  5. З Chrome чи Firefox цього не відбувається. FF надсилає один пакет так, схоже, взагалі уникне цього питання.

  6. Це відбувається в IE 6, 7, 8. Не вдалося відтворити за допомогою IE 9 beta.


4
Чи є інші способи виправити цю проблему? Будь-яке виправлення javascript? Я спробував переглянути різні об’єкти XMLHTTP, і вони все ще не вирішили проблему.
Берлін Браун

11

Стаття про microsoft KB під назвою Коли ви використовуєте Microsoft Internet Explorer або іншу програму для повторної операції POST, ця проблема, як видається, розміщується лише в заголовку .

У статті подано виправлення. Для пізніших веб-переглядачів, таких як IE8, він каже, що виправлення вже включено, але його потрібно ввімкнути через налаштування реєстру на клієнтському ПК.


1
У мене виникає ця проблема з IE10, про яку в статті не йдеться.
ClearCloud8

6
Зараз у статті згадується IE11, тому, схоже, це ніколи не було виправлено.
пітер

Я вважаю, що у мене виникає ця проблема на виробничому сайті - агенти користувачів, пов’язані з проблемою, відповідають IE 8,9,10 та 11.
millhouse

Хтось знайшов рішення? Зокрема, я надсилаю дані 307, а FF, Chrome, Safari переносять дані на нову кінцеву точку - IE ні. Я не можу попросити своїх користувачів виправлення / виправлення реєстру.
Бред Ганн

2

У мене була схожа проблема, коли деякі старіші версії IE надсилали назад лише Header, а не тіло POST. Моя проблема виявилася пов'язаною з IE та NTLM. Оскільки ви не згадали про NTLM, це, мабуть, не допомагає, але про всяк випадок:

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


Ваше посилання було корисним у вирішенні подібної проблеми в IE 11 та IIS 6.
Шкідливість

1

Це довгий огляд, але IE (і навіть Firefox) іноді "запам'ятовує" з'єднання, яке воно використовує для HTTP-запиту. Примітки / приклади:

  • У Firefox, якщо я зміню налаштування проксі-сервера і натисніть кнопку SHIFT-RELOAD на сторінці, він все ще використовує старий проксі. Однак, якщо я вбиваю старий проксі ("кальмар кіллала"), він починає використовувати новий проксі.

  • Коли ви від'єднаєтесь / підключитесь, ви отримуєте нову IP-адресу чи щось подібне? Чи можете ви якимось чином відстежувати стару IP-адресу, щоб побачити, чи IE надсилає дані на цю тепер мертву адресу?

  • Я здогадуюсь, що IE надсилає дані, просто вниз неправильним шляхом. Це може бути досить розумним, щоб не кешувати мережеві з'єднання для пакетів "POST", але може бути недостатньо розумним для цього для корисних навантажень POST.

  • Це, мабуть, не стосується більшості програм AJAX, оскільки люди рідко відключаються та знову підключаються до своїх мереж?


2
Я думаю, проблема остання. Я думаю, що Microsoft використовує політику "рідко: не реалізуй". :)

1
Я стежу за усім трафіком HTTP від ​​джерела до місця призначення. Я можу підтвердити, що (а) моя IP-адреса не змінилася і (б) немає спроби надіслати щось інше. IE відкриває нову розетку і надсилає частковий запит. Те, як я читав статтю MS, - це одне з їх оновлень безпеки, порушив IE. Потім вони створили виправлення, щоб виправити це. Але на всякий випадок, якщо ви хочете, щоб він поводився по-старому "зламаним" способом, ви можете додати цей ключ реєстру. Повторити_HeaderOnlyPOST_OnConnectionReset. Просто намагаюся осмислити божевілля.
Dodgyrabbit

Останнє: якщо у вас є програма Ajax, яка періодично опитується, скажімо, 10 секунд, ми виявимо, що якщо її відкрити на кілька годин, ця помилка незмінно відбудеться. Можливо, підключення до Wi-Fi, яке випадає або є схематичною мережею, - але ми відчуваємо, що ця проблема є реальною.
Dodgyrabbit

1

Чи використовуєте ви автентифікацію NTLM?

Під час використання автентифікації NTLM IE не надсилає поштові дані. Він надсилає інформацію заголовка, очікує несанкціонованої відповіді надіслати авторизацію та після "повторної аутентифікації" надсилає повідомлення.


Ми не використовуємо аутентифікацію NTLM. Відбувається з анонімними запитами.
Dodgyrabbit

0

У мене була подібна проблема сьогодні при використанні $ .ajax, і я зміг її виправити, встановивши функцію async на false.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.