3rg*_*rgo 13 javascript iframe
我<iframe>在我的应用程序(使用ExtJS 4.2的单页面应用程序)中使用(我知道,我知道......)进行文件下载,因为它们包含大量数据并且可能需要一段时间来生成Excel文件(我们根据参数,从20秒到20分钟说话.
当前的状态是:当用户点击下载按钮时,他被Javascript(window.location.href = xxx)"重定向" 到执行导出的页面,但由于它是在PHP中完成的,并且没有发送标题,浏览器会不断加载页面,直到文件下载.但它不是非常用户友好,因为没有任何东西显示它是否仍在加载,完成(文件下载除外)或失败(这导致页面实际重定向,可能使他失去他正在做的工作).
所以我创建了一个停靠在右下角的小型非模态窗口,其中包含iframe以及一条小消息以确保用户放心.我需要的是能够检测何时加载并能够区分2种情况:
但是,我尝试了所有4个事件(W3Schools的文档),并没有被永远开除.我至少可以理解,如果它不是返回的HTML数据,它可能无法触发事件,但即使我强制错误返回文本数据,它也不会被触发.
如果有人知道这个的解决方案,或者可能适合这里的替代系统,我全都耳朵!谢谢 !
编辑:添加iframe代码.我们的想法是获得一个更好的方法来关闭它而不是一个setTimeout.
var url = 'http://mywebsite.com/my_export_route';
var ifr = $('<iframe class="dl-frame" src="'+url+'" width="0" height="0" frameborder="0"></iframe>');
ifr.appendTo($('body'));
setTimeout(function() {
$('.dl-frame').remove();
}, 3000);
Run Code Online (Sandbox Code Playgroud)
我想知道它是否需要在前端和后端代码中进行一些重大更改,但您是否考虑过使用AJAX?工作流程将是这样的:用户发送AJAX请求以启动文件生成,并且前端不断地从服务器轮询它的状态,当它完成时 - 向用户显示下载链接.我相信工作流程会更直接.
好吧,你也可以尝试这个技巧.在父窗口中为iframe的完整加载创建一个回调函数myOnLoadCallback,然后从iframe中调用它parent.myOnLoadCallback().但您仍然需要使用setTimeout来处理服务器错误/连接超时.
最后一件事 - 你是怎么试图抓住iframe的事件的?也许它与浏览器有关.您是否尝试过直接在HTML属性中设置事件回调?喜欢
<iframe onload="done()" onerror="fail()"></iframe>
Run Code Online (Sandbox Code Playgroud)
我知道这是一种不好的做法,但有时候工作需要快速完成,是吗?
更新
嗯,我担心你必须花一个漫长而痛苦的一天使用JS调试器.load事件应该有效.不过我还是有一些建议:
1)尝试在设置元素之前设置事件监听器src.也许onload事件发生得如此之快,以至于它在创建元素和设置事件的回调之间滑动
2)同时尝试检查你的服务器代码是否与iframe很好地配合.我做了一个简单的测试,试图从Dropbox下载PDF,尝试用你支持的路由替换我的URL.
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<iframe id="book"></iframe>
<button id="go">Request downloads!</button>
<script>
var bookUrl = 'https://www.dropbox.com/s/j4o7tw09lwncqa6/thinkpython.pdf';
$('#book').on('load', function(){
console.log('WOOT!', arguments);
});
$('#go').on('click', function(){
$('#book').attr('src', bookUrl);
});
</script>
Run Code Online (Sandbox Code Playgroud)
更新2
3)另外,查看浏览器调试器的"网络"选项卡,当您设置src为iframe 时会发生什么,它应该显示请求和服务器对标头的响应.
我尝试过使用 jQuery,效果很好,正如您在这篇文章中看到的那样。
我在这里做了一个工作示例。
基本上是这样的:
<iframe src="http://www.example.com" id="myFrame"></iframe>
Run Code Online (Sandbox Code Playgroud)
和代码:
function test() {
alert('iframe loaded');
}
$('#myFrame').load(test);
Run Code Online (Sandbox Code Playgroud)
在 IE11 上测试。
小智 2
也许你应该使用
$($('.dl-frame')[0].contentWindow.document).ready(function () {...})
Run Code Online (Sandbox Code Playgroud)