Ajax文件下载问题

6
我正在我的应用程序中下载一个动态文件,使用iframe模拟ajax。我的做法是,在发出下载请求时,我将创建一个动态不可见的iframe,并将我的iframe的src设置为下载url。我能够成功地下载文件,但要求在下载开始时显示下载指示器,并且当下载对话框出现时应该立即完成。我在iframe创建后提供了回调来显示下载指示器,这很成功,还在iframe的'onload'上提供了另一种方法,希望在下载对话框出现时调用它。但不幸的是,那不起作用,因此即使下载完成,我的进度指示器仍然存在。我无法删除它。然后我意识到,由于响应的内容类型不是html,它将由单独的进程提供,这会导致下载对话框,因此我的onload方法从未被调用。请告诉我一个解决方案。
5个回答

15
我创建了 jQuery文件下载插件 (演示),它可以解决这个问题并提供一些其他不错的功能。它基本上为文件下载提供了一个“完整的 Ajax-like”体验(甚至包括回调函数),这在通常情况下是不可能的。它的工作方式与其他答案类似,使用 iframe,但具有一些很酷的功能,我发现非常方便:
  • 用户无论成功还是出现错误,都不会离开他们启动文件下载的同一页
  • successCallback 和 failCallback 函数允许您明确指定任何情况下 UI 行为
  • 与 jQuery UI 结合使用,开发人员可以轻松显示模态窗口,告诉用户文件正在下载,下载开始后取消模态窗口,甚至以友好的方式告知用户出现错误。请参见 演示 以获取示例。
这是一个使用带有Promise的插件source的简单用例演示。demo page包括许多其他“更好的用户体验”示例。
$.fileDownload('some/file.pdf')
    .done(function () { alert('File download a success!'); })
    .fail(function () { alert('File download failed!'); });

2

这就是我一直在寻找的。谢谢! :) - Tony

1
当下载请求发出时,您应该在客户端启动一个计时器,以指定的时间间隔测试 iframe 的状态:
if ( ( iframe.document && iframe.document.readyState == 'complete' )
    || iframe.contentDocument )
{
    stopTimer();
    closePopupDialog();
}

上面的解决方案非常接近,但在我的情况下,即使下载完成,readyState也从未达到“complete”状态,它仍然处于“interactive”状态。有什么想法是什么问题? - Bibin
刚刚得知,content-disposition 在其中起了作用。请查看 **此链接**。 - Bibin
这种方法不幸地无法工作,因为不同浏览器的readyState行为不一致。例如,Chrome的永远不会改变。 - John Culviner

1

0

你可以使用一个闪存下载管理器 - 谷歌会显示大量的这类工具。

你的另一个选择是使用真正的AJAX。只需向下载URI发出请求,当收到响应时,使用XMLHTTPRequest对象的responseBody属性而不是responseText属性。

你需要一种将其写入硬盘的方式,在IE中可以通过放松安全约束并使用ActiveXObject "Scripting.FileSystemObject"来完成。你可能可以使用数据URI方法:http://en.wikipedia.org/wiki/Data_URI_scheme以Base64编码,但我不确定那是否可行。

否则,你就得回到使用Flash来将通过ajax下载的数据写入磁盘。

如果你知道动态下载的大小并且规范中不需要精确的时间,则可以在下载之前进行Internet速度检查,将一些缓冲时间添加到计算出的下载文件所需的时间中,并只在给定的时间段内显示对话框。这样做很hackish,但再次说回去,这个方案似乎有点像营销需要它,所以就让它存在了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接