Бесконечное сообщение «Соединение» после отправки формы AJAX - PullRequest
8 голосов
/ 02 сентября 2011

У меня есть класс, который позволяет отправлять формы с вводом файлового типа через AJAX.Он создает скрытый элемент IFRAME, изменяет свойство формы target так, чтобы он отправлялся в IFRAME, отправлял форму, а затем изменял цель на прежнюю.Он также добавляет событие onLoad к IFRAME, чтобы я мог получить обратный вызов.Функция onLoad также удаляет IFRAME со страницы перед запуском моей функции обратного вызова.

Класс работает отлично, я получаю обратный вызов, как и ожидалось.В сетевой панели Firebug я вижу запрос, вижу ответ, все хорошо.Но, как только начинается отправка, вкладка браузера для страницы меняется на «Соединение» с загрузчиком и никогда не изменяется обратно.Похоже, что вкладка загружается, это будет продолжаться в течение дней , если я оставлю браузер открытым.

The never-ending

Тогда возникает вопрос: Можно ли как-нибудь остановить это вручную или есть какой-то другой способ, которым я могу предотвратить его запуск?

Вот заголовки ответа, взятые из панели Net:

Date    Fri, 02 Sep 2011 15:23:15 GMT
Server  Apache/2.2.10 (Win32) PHP/5.3.1
X-Powered-By    PHP/5.3.1
Expires Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control   no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma  no-cache
Set-Cookie  PHPSESSID=agncdnha86mtci7dmuvriobak2; path=/
Content-Length  165
Keep-Alive  timeout=5, max=100
Connection  Keep-Alive
Content-Type    text/html

И снимок панели Net ниже.POST от представления формы, GET вызван функцией обратного вызова, он изменяет источник изображения на странице.

Screenshot of Firebug's Net panel

Это не является определеннымна этой странице это происходит везде, где я использую эту технику для отправки файла / изображения через IFRAME.Это влияет на мою текущую версию Firefox (6.0), но также влияет на предыдущие версии (5.x, 4.x, 3.x).Тот факт, что IFRAME удаляется со страницы после его загрузки, делает это особенно затруднительным - даже если запрос никогда не завершается, удаление элемента должно эффективно уничтожить / остановить и «соединиться», что, по мнению обозревателя, происходит.

ОБНОВЛЕНИЕ В ответе @Sidnicious я добавил тайм-аут в функцию обратного вызова, чтобы ввести задержку при удалении элемента IFRAME.Я экспериментировал с длительностью задержки, даже 1 мс задержка является адекватной.Это, безусловно, можно рассматривать как обходной путь, но я все же хотел бы знать, может ли кто-нибудь пролить свет на , почему он , предпочтительно, чтобы избежать одновременного использования тайм-аута.Я включил модифицированный код (с тайм-аутом) ниже, на случай, если это будет полезно.Это событие onLoad для IFRAME (io us ссылка на элемент frame):

        var obj={};
        var success = true;
        try{
            obj.responseText = io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null;
            obj.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document;
        }
        catch(e){ success = false; }
        if( success ){
            this.fireEvent('onSuccess', obj.responseText );
        }else{
            this.fireEvent('onFailure', obj );
        }
        this.fireEvent('onComplete', obj );
        io.removeEvent('load', uploadCallback );
        setTimeout(function () { // <--- this timeout prevents the issue
            io.dispose();
        }, 1);

Ответы [ 2 ]

7 голосов
/ 06 сентября 2011

Обновление: ошибка Firefox теперь помечена как «исправленная» и превратит ее в ближайшее обновление.


Я тоже столкнулся с этим и хотел бы love чтобы исправить основную причину.

  • Я разговаривал с парой разработчиков Firefox (mbrubeck и gavin), и они думают, что это ошибка! О той же проблеме сообщалось и исправлено в 2005 году для Firefox 1.9.Затем ошибка 489259 была открыта в 2009 году. Mbrubeck любезно переместил ее из «неподтвержденной» стопки.

  • Safari ведет себя лучше, чем Firefox, но сообщение об ошибке(«Одна ошибка при открытии страницы…») отображается в строке состояния, если вы удалите iframe во время события load.Я обнаружил две похожие ошибки WebKit, которые были открыты с 2007 года: 15485 и 13281 .

Это происходит, когда вы удаляете iframe из документа во время события load.События JavaScript запускаются синхронно - то есть последовательно с собственной обработкой веб-страницей браузером.Вот почему можно предотвратить отправку формы или предотвратить регистрацию нажатия клавиши мыши или нажатия мыши из обработчика событий.

В последний раз, когда эта ошибка была исправлена ​​в Firefox, причиной было то, что удалениеiframe со страницы заставляет забыть, какой странице она принадлежала, но iframe уведомляет страницу о том, что она закончила загрузку после события load.

Все, что вы запланировали сsetTimeout происходит после текущего цикла цикла событий - после того, как браузер завершает свою работу прямо сейчас .Поэтому, используя setTimeout для удаления iframe, даже с нулевым тайм-аутом, он может завершиться:

iframe.onload = function(){
    // Do work with the content of the iframe…

    setTimeout(function(){
        iframe.parentNode.removeChild(iframe);
    }, 0);
}

Вы можете найти эту технику в использовании в плагине формы jQuery .

2 голосов
/ 06 сентября 2011

Событие onload в вашем IFRAME не выполняется полностью, поскольку оно прерывается удалением вашего IFRAME.В Firefox есть ошибка, из-за которой он не вызывает свой внутренний код после прерывания события onload.

Устанавливая таймаут, Firefox безошибочно выполняет onload, после чего выполняется обратный вызов тайм-аута и IFRAMEустранен.В соответствии с документацией тайм-аут может также сработать позже, когда страница (или сама ОС / браузер) занята другими задачами (например, удалением IFRAME).

...