在AJAX表单提交后永无止境的“正在连接”消息

时间:2011-09-02 15:38:52

标签: javascript ajax firefox iframe mootools

我有一个类,它允许通过AJAX提交带有文件类型输入的表单。它会创建一个隐藏的IFRAME元素,更改形式target属性,以便它提交到IFRAME,提交表单,然后将目标更改回原来的状态。它还会向onLoad添加IFRAME事件,以便我可以收到回调。在激活我的回调函数之前,onLoad函数还会从页面中删除IFRAME

该类工作正常,我得到了预期的回调。在Firebug的Net面板中,我看到了请求,我看到了响应,一切都很顺利。但是,一旦提交开始,页面的浏览器选项卡将更改为“正在连接”加载微调器,并且永远不会更改回来。它使标签显示正在加载,如果我打开浏览器,这将持续

The never-ending "Connecting" message that plagues me

那么问题是:我有什么方法可以手动停止此操作,还是有其他方法可以阻止它启动?

以下是从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元素的延迟。我试验了延迟的长度,即使1ms的延迟也足够了。这当然有资格作为一种解决方法,但我仍然想知道是否有人可以对为什么有所了解,最好是避免一起使用超时。我已经在下面包含了修改后的代码(带有超时),以防它有用。这是onLoad的{​​{1}}事件(IFRAME我们对框架元素的引用):

io

2 个答案:

答案 0 :(得分:7)

更新:Firefox错误现已标记为“已修复”,并将进入近期更新。


我也遇到过这种情况,并且以确定修复根本原因。

  • 我和几个Firefox开发人员(mbrubeck和gavin)谈过,他们认为这是一个错误! 2005年为Firefox 1.9 The same issue was reported, and fixed,。然后,bug 489259于2009年开放.mbrubeck慷慨地将其从“未经证实的”堆中移出。

  • Safari的行为优于Firefox,但如果您在load事件期间删​​除了iframe,则会在状态栏中显示错误消息(“打开页面时出现一次错误...”)。我发现了两个类似的WebKit错误,这些错误自2007年以来一直开放:1548513281

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);
}

您可以使用in the jQuery form plugin找到此技术。

答案 1 :(得分:2)

IFRAME中的onload事件未完全执行,因为它会因删除您的IFRAME而中断。 Firefox有一个错误,它在中断onload事件后不会调用它的内部代码。

通过设置超时,Firefox干净地执行onload,之后运行超时回调并删除IFRAME。根据{{​​3}},当页面(或操作系统/浏览器本身)忙于其他任务(即删除IFRAME)时,超时也会稍后触发。