Html Ajax 文件下载问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1538741/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 01:00:51  来源:igfitidea点击:

Ajax File download Issue

htmlajaxiframedownload

提问by Bibin

I am downloading a dynamic file in my application, simulating ajax using iframes. What I am doing is, when the download request is made, I will create a dynamic invisible iframe, and set the src of my iframe as the download url.I am able to successfully download the file, but the requirement is to show a download indicator once the download starts and that should finish as soon as the download dialog comes up.I provided call back after iframe creation to show the download indicator, which is successfully working, and provided another method on the 'onload' of the iframe, expecting it will be invoked, when the download dialog comes up. But unfortunately, that is not working, and because of that even after the download completes, my progress indicator is still there. I am not able to remove that. Then I came to realize that the since the content type of the response is not html, it will be served by a separate process, which leads to the download dialog and because of that my onload method is never getting called. Please let me know a solution for this.

我正在我的应用程序中下载一个动态文件,使用 iframe 模拟 ajax。我在做的是,当有下载请求时,我会创建一个动态的不可见iframe,并将我的iframe的src设置为下载url。我能够成功下载文件,但要求是显示一个下载一旦下载开始并应在下载对话框出现后立即完成。我在 iframe 创建后提供回调以显示下载指示器,该指示器已成功工作,并提供了关于 iframe 的“加载”的另一种方法,期待当下载对话框出现时,它将被调用。但不幸的是,这不起作用,因此即使在下载完成后,我的进度指示器仍然存在。我无法删除它。然后我意识到,由于响应的内容类型不是 html,它将由一个单独的进程提供,这会导致下载对话框,因此我的 onload 方法永远不会被调用。请让我知道一个解决方案。

采纳答案by Dave Spurling

You should start a timer in the client when the download request is made which tests the state of the iframe at a specified interval:

您应该在发出下载请求时在客户端启动一个计时器,以指定的时间间隔测试 iframe 的状态:

if ( ( iframe.document && iframe.document.readyState == 'complete' )
    || iframe.contentDocument )
{
    stopTimer();
    closePopupDialog();
}

回答by John Culviner

I created the jQuery File Download plugin(Demo) which also fixes the problem and provides some other nice features. It basically gives you a "full Ajax-like" experience for file downloads (complete with callbacks even) that isn't normally possible for file downloads. It works pretty similarly to some other answers with an iframe but has some cool features that I have found quite handy:

我创建了jQuery 文件下载插件( Demo),它也解决了这个问题并提供了一些其他不错的功能。它基本上为您提供了“完整的类似 Ajax”的文件下载体验(甚至带有回调),这通常无法用于文件下载。它的工作原理与 iframe 的其他一些答案非常相似,但有一些很酷的功能,我发现这些功能非常方便:

  • User never leaves the same page they initiated a file download from whether it is successful or there is an error
  • successCallback and failCallback functions allow for you to be explicit about what the UI behavior is in either situation
  • In conjunction with jQuery UI a developer can easily show a modal telling the user that a file download is occurring, disband the modal after the download starts or even inform the user in a friendly manner that an error has occurred. See the Demofor an example of this.
  • 用户永远不会离开他们启动文件下载的同一页面,无论是成功还是有错误
  • successCallback 和 failCallback 函数允许您明确说明在任何一种情况下的 UI 行为
  • 结合 jQuery UI,开发人员可以轻松地向用户显示一个模式,告诉用户正在下载文件,在下载开始后解除模式,甚至以友好的方式通知用户发生了错误。有关此示例,请参阅演示

Here is a simple use case demo using the plugin sourcewith promises. The demo pageincludes many other, 'better UX' examples as well.

这是一个使用带有 promise的插件的简单用例演示。该演示页包含了许多其他“更好的UX”的例子也是如此。

$.fileDownload('some/file.pdf')
    .done(function () { alert('File download a success!'); })
    .fail(function () { alert('File download failed!'); });

回答by prasad

回答by Marcus Pope

You can use a flash download manager - google will reveal a slew of them.

您可以使用 Flash 下载管理器 - 谷歌会显示其中的一大堆。

Your other option is to use real AJAX. Simply make a request to the download URI, and when you get your response, use the responseBody instead of the responseText attribute of the XMLHTTPRequest object.

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

You'll need a way to write that to the harddrive, which can be done in IE with lax security constraints and the ActiveXObject "Scripting.FileSystemObject" You might be able to use the data uri approach: http://en.wikipedia.org/wiki/Data_URI_schemewith a base64 encoding, but I'm not sure if that will work.

您需要一种将其写入硬盘的方法,这可以在具有宽松安全约束和 ActiveXObject“Scripting.FileSystemObject”的 IE 中完成 您也许可以使用数据 uri 方法:http://en.wikipedia。 org/wiki/Data_URI_scheme使用 base64 编码,但我不确定这是否可行。

Otherwise you're back to flash to write the data you downloaded via ajax to disk.

否则,您将返回闪存以将您通过 ajax 下载的数据写入磁盘。

If you know the size of the dynamic download and exact timing isn't required in the specification, then you could do an internet speed check before the download, add some buffer time to the calculated time it will take to download the file, and just show the dialog box for that given period of time. Very hackish, but then again this scheme seems a little marketing-requires-it-to-be-so-it-shall-be

如果您知道动态下载的大小并且规范中不需要确切的时间,那么您可以在下载之前进行网速检查,在计算出的下载文件所需的时间中添加一些缓冲时间,然后就可以了显示给定时间段的对话框。非常骇人听闻,但话说回来,这个计划似乎有点营销 - 需要它是这样的