我有一个类,它允许通过AJAX提交带有文件类型输入的表单。它会创建一个隐藏的IFRAME
元素,更改形式target
属性,以便它提交到IFRAME
,提交表单,然后将目标更改回原来的状态。它还会向onLoad
添加IFRAME
事件,以便我可以收到回调。在激活我的回调函数之前,onLoad
函数还会从页面中删除IFRAME
。
该类工作正常,我得到了预期的回调。在Firebug的Net面板中,我看到了请求,我看到了响应,一切都很顺利。但是,一旦提交开始,页面的浏览器选项卡将更改为“正在连接”加载微调器,并且永远不会更改回来。它使标签显示正在加载,如果我打开浏览器,这将持续天。
那么问题是:我有什么方法可以手动停止此操作,还是有其他方法可以阻止它启动?
以下是从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是由回调函数引起的,它正在改变页面上图像的来源。
这不是特定于此页面,它发生在我使用此技术通过IFRAME
提交文件/图像的任何地方。这会影响我当前版本的Firefox(6.0),但也影响以前的版本(5.x,4.x,3.x)。加载后IFRAME
从页面中删除的事实使得这一点特别令人困惑 - 即使请求永远不会完成,元素的删除也应该有效地杀死/停止和“连接”浏览器认为正在发生的事情。
更新
根据@Sidnicious的回答,我在回调函数中添加了一个超时,以引入删除IFRAME
元素的延迟。我试验了延迟的长度,即使1ms的延迟也足够了。这当然有资格作为一种解决方法,但我仍然想知道是否有人可以对为什么有所了解,最好是避免一起使用超时。我已经在下面包含了修改后的代码(带有超时),以防它有用。这是onLoad
的{{1}}事件(IFRAME
我们对框架元素的引用):
io
答案 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年以来一直开放: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);
}
您可以使用in the jQuery form plugin找到此技术。
答案 1 :(得分:2)
IFRAME中的onload
事件未完全执行,因为它会因删除您的IFRAME而中断。
Firefox有一个错误,它在中断onload
事件后不会调用它的内部代码。
通过设置超时,Firefox干净地执行onload
,之后运行超时回调并删除IFRAME。根据{{3}},当页面(或操作系统/浏览器本身)忙于其他任务(即删除IFRAME)时,超时也会稍后触发。