在javascript中等待文件下载时进度/忙碌指示器?

时间:2009-05-15 13:08:57

标签: javascript html

情况如下: 在Web应用程序中,用户选择一些选项,提交表单,PDF文件在服务器端动态生成并提供下载。

问题: 生成PDF文件需要很长时间(最多1分钟)。有些用户认为没有什么是hapening并且不断地再次点击提交按钮并再次增加服务器负载并进一步减慢它。

我想添加一些繁忙的指示器,它会显示动画图片和“请等待,你的文件正在生成”这样的消息,这看起来很容易。

但是:当文件准备好并弹出“文件下载”对话框时,如何隐藏此指示器?否则,即使用户下载了文件,该消息仍会保留在屏幕上!

似乎是非常基本的要求,但我完全陷入困境。谢谢你的任何建议!

7 个答案:

答案 0 :(得分:5)

我必须为那些花费更长时间(转换视频格式)的事情做这件事。这对你来说似乎有些过分,但确实有效。

  1. 将您的PDF代码移出流程。
  2. 当作业开始时,创建一个唯一的作业ID并将其保存到会话中。告诉PDF创建者这个ID。
  3. 让它将状态文件(命名为作业ID)写入服务器,使其写入“0%完成”并每隔几秒更新一次(此部分取决于您是否能够在流程中获得进度指标) ......如果没有那么这将不起作用)
  4. 使用JS拉下该文件。您可以向用户显示进度。
  5. 当进度等于“100%完成”时,将它们推送到PDF的位置。如果您将其命名为作业ID,可能会有所帮助。*
  6. *我们有另一个下载脚本,使用content-disposition标题将其重命名为一个漂亮的名称(基于原始视频文件名),但这完全取决于您!

    编辑:我应该添加等待页面是单击提交的结果。这是一个新的页面加载,但没有理由你不能在整个过程中使用AJAX,只要确保像其他人所说的那样,在第一次点击时禁用提交按钮以阻止用户对其进行操作。

答案 1 :(得分:2)

我同意其他受访者的意见,您最好的选择是禁用表单上的提交按钮,并给用户一个忙碌的指示;然而,对于需要很长时间才能生成文件的文件来说,为用户提供一个更实际的指示器确实是有意义的。

您可能能够实现状态栏或更新等待消息的一种方法是让客户端JavaScript对服务器进行初始调用,并让服务器在开始生成后立即响应。然后,您可以让客户端JavaScript每隔 n 秒轮询服务器,以查看文件是否完整。如果您有办法确定文件生成状态,那么您可以为进度条百分比提供数字响应,或者您可以回复“仍在工作”类型的消息。

我相信this blog on asp.net讨论了类似的设置。

答案 2 :(得分:2)

我有一篇博文,内容可能解决此问题:

http://geekswithblogs.net/GruffCode/archive/2010/10/28/detecting-the-file-download-dialog-in-the-browser.aspx

这种方法涉及客户端和服务器端代码之间的一些合作。它的工作原理如下(包括代码的完整示例可以在我上面链接的博客文章中找到):

  • 用户点击“提交”按钮生成文件。 将数据提交给要处理的服务器之前,客户端javascript做了三件事:
    1. 生成“令牌”值并设置为要提交的HTML表单中的隐藏字段。令牌的价值并不重要;只使用当前日期&第二个时间戳应该足够了。
    2. 在设置令牌之后但仍然允许提交表单之前,客户端代码会发出“系统忙”消息,让用户知道发生了某些事情并阻止他们两次提交表单。 jQuery BlockUI plugin非常适用于此目的。
    3. 最后,配置时间以定期轮询是否存在具有预定义名称的cookie,该名称包含在步骤1中创建的令牌值。
  • 现在,客户端上有一个很好的“封面”,让用户知道发生了什么事情,并阻止他们点击按钮两次,同时可以在服务器端处理请求。在将完成的文件作为下载发送回客户端之前,在HTTP响应中设置一个包含预定义名称的cookie,其中包含客户端提交的令牌值。
  • 当客户端收到HTTP响应时,轮询包含令牌值的预定义cookie名称的计时器代码将找到它,然后可以执行以下操作:
    1. 取消阻止用户界面
    2. 停止计时器/轮询代码。

我通常以1秒的轮询间隔执行此操作,因此大多数用户必须在浏览器中显示文件下载对话框的时间与“系统忙”消息消失的时间之间等待1秒。 / p>

在我看来,这种方法非常快速且易于实施。也就是说,鉴于您的PDF生成大约需要1分钟,我认为您已经接近了“在带外”处理该处理并实现类似于接受的答案中所解释的内容的可能性。

答案 3 :(得分:1)

您可以异步轮询服务器(例如使用AJAX)来检查该特定PDF的生成是否已完成。 根据该结果或超时重新启用该按钮和/或停止动画。

答案 4 :(得分:0)

我会在onSubmit事件中添加或类似的东西。 Busy块可以只是一个在后台有ajax load动画的div。 (我确实建议使用动画gif,而不是Javascript动画。)一旦输出返回,用户将在等待一分钟后看到PDF。您甚至可以使用计时器来减少估计值(比如说60秒)并让用户知道可能需要多长时间。

document.getElementById('busy').style.display = 'block';
document.getElementById('submit').disabled = 'disabled';

繁忙的街区:

<div id="busy">
  <p>Your PDF is being generated, please wait.</p>
</div>

通用CSS ......

#busy { display: none; background: url(/images/spinner.gif) no-repeat top left; padding-left: 24px; }

答案 5 :(得分:-1)

不是您问题的完整答案,但您可以在用户首次点击时停用提交按钮。

这将解决“用户不断点击从而进一步降低服务器速度”的问题。

答案 6 :(得分:-1)

感谢大家的建议。

与此同时,我尝试了另一种方法:

a)在“onclick”中,禁用“提交”按钮并显示忙碌指示符。 b)在服务器端,生成文件时,不要将其输出给用户,而是将其保存到文件系统。然后,将重定向发送到同一页面,但属性为“&amp; downloadready = true” c)在页面加载时,如果“downloadready”属性为true,则启动文件下载。

它有效,但有一个缺点:在IE中,它显示警告“为了保护您的安全,IE阻止了文件下载bla bla bla”,这对用户来说非常烦人,我想。

那么,让我们尝试一下AJAX轮询方法。