【问题标题】:Getting XMLHttpRequest Progress from PHP Script从 PHP 脚本获取 XMLHttpRequest 进度
【发布时间】:2011-04-28 19:16:06
【问题描述】:

我正在使用 javascript 对返回数据的 PHP 脚本运行 XMLHttpRequest。基本上我希望能够为用户提供一个进度条(而不是一个旋转的圆圈或其他东西),它显示了获取和接收数据的进度。我知道如果我得到一个文件,我可以检查内容长度标题并使用它,但对于脚本,你不知道它正在检索多少数据。

这个问题的答案可能就像“不可能”一样简单,因为现在看起来就是这样。但总而言之:您如何通过 XMLHttpRequest 监控正在运行的脚本 (php) 的进度?

【问题讨论】:

  • 可能有十几种不同的方法来做到这一点。这取决于 PHP 脚本在做什么,以及你拥有什么样的服务器端技术。你能说得更具体点吗?
  • 脚本正在运行查询并使用数据生成 html 代码,xmlhttprequest 响应处理程序将其插入当前页面。

标签: php javascript xmlhttprequest


【解决方案1】:

您可以使用 2 个 ajax 请求。一个启动并等待作业完成,另一个检查作业进度。我很确定大多数浏览器一次至少可以执行 2 个 ajax 请求。

实际执行这项工作的 PHP 脚本(我们称之为 job.php)可以使用作业完成的百分比更新会话变量 $_SESSION['job_progress']。

你有另一个 PHP 脚本(我们称之为progress.php)来回显该值,即

<?php echo $_SESSION['job_progress'];

客户端向job.php 发出ajax 请求。您有另一个每 3 秒运行一次的对 progress.php 的 ajax 请求。您使用返回的值更新进度条。

如果对 job.php 的请求在作业完成之前返回,您也可以使用一个 ajax 请求来执行此操作。然后您可以继续使用单个 ajax 请求来 ping progress.php 脚本。

【讨论】:

  • 我想他想知道到目前为止他收到了多少字节的 XHR 请求文件。
  • @Gordon - 同样的概念也适用。
  • PHP 没有记录通过给定连接发送了多少字节,所以我真的不明白使用第二个连接询问它会有什么帮助。如果您将 PHP 设置为执行需要很长时间才能运行的作业,您可以使用您的解决方案询问它在作业完成之前需要多长时间,但如果作业完成得非常快但结果在要发送的大量数据中,这种方法效果不佳。
  • @Gordon - 他的问题表明他的 ajax 请求正在回调 PHP 脚本。因此,如果他正在获取一个文件,那么他会使用 PHP 在请求中将其流回,在这种情况下,他可以更新会话值以报告进度。
【解决方案2】:

在某些浏览器(其中之一是 firefox)中,会多次调用带有 readyState 3(即加载)的 onreadystatechange,因此可以监控下载进度。

此外,在某些浏览器中,responseText 属性包含到目前为止返回的结果,可以对其进行检查以了解进度。

但是Internet Explorer(至少对于IE7,以后不确定)不支持这个,查询readyState 3的responseText或responseBody是错误的。我也听说IE只调用onreadystatechange一次 使用 readyState 3 会使其对您的目的毫无用处,但我建议对其进行测试。

【讨论】:

    【解决方案3】:

    创建一个会话。 (可能,你已经有一个)。 当您请求它开始处理时,为查询创建一个 UID。

    随着查询的进行,将进度与 SID+UID 一起存储在服务器上的某处(在数据库、文件中等)。

    使用带有计时器的第二个 ajax 请求通过 SID+UID 轮询进度。

    *您可能只能通过 UID 获取,但我发现当您还可以按用户/会话监控任务时,它更易于管理。

    【讨论】:

      【解决方案4】:

      如果您使用的是 FireFox(我相当确定除 IE 之外的大多数其他浏览器),那么确实有一种方法可以报告在 XHR 操作期间传输了多少数据。如果有问题的操作发送了正确的标头,则使用此信息来计算下载数据的百分比相当容易。

      几年前我编写了这段代码来确定 XHR 操作中传输的数据百分比,因此我很抱歉它没有反映我从那以后获得的多年编码经验。我几乎肯定不会现在这样写!尽管如此,我还是设法把它捞了出来,希望它对你有用。

      在撰写本文时,IE7 是可用的最新版本的资源管理器,我记得代码在其中不起作用,因此它包含防止它在 IE 下初始化的代码。我从未在版本 8 或版本 9 的 beta 版下尝试过此代码,它可能确实也适用于这些版本,但我不能保证。如果你可以让它在新版本的 IE 中运行,请告诉我!

      它通过在 beforeSend 中运行代码(一个回调 jQuery 为您在启动 ajax 请求之前运行的代码提供了一个回调)来设置 Javascript 间隔(在代码中我设置了 50 毫秒,这可能太频繁了) . 200 毫秒应该仍然足够,并且对系统施加的压力较小)。每次间隔计时器触发时,它都会运行一个查看 XHR 请求的 responseText 属性的函数。 responseText 属性保存到目前为止接收到的数据的原始文本。通过使用 length() 字符串方法计算其中有多少字符,我们可以算出到目前为止已经收集了多少字节。

      就计算要发送的总数据的百分比而言,这将要求您的服务器端代码发送一个内容长度标头,其中包含要发送的字节数的准确计数。这需要你有一点聪明,但应该不会太难。如果您发送准确的内容长度标头,则它用于计算到目前为止接收到的数据的百分比。如果您不设置内容标头,则会显示到目前为止接收到的数据量。

      <script type="text/javascript">
      $.ajax ({
          beforeSend  : function (thisXHR)
          {
              // IE doesn't support responseText access in interactive mode
              if (!$.browser.msie)
              {
                  myTrigger = setInterval (function ()
                  {
                      if (thisXHR.readyState > 2)
                      // When there is partial data available use it to determine how much of the document is downloaded
                      {   
                          var dlBytes = thisXHR.responseText.length;
                          if (totalBytes == -1)
                              totalBytes  = thisXHR.getResponseHeader ('Content-length');
                          (totalBytes > 0)?
                              $('#progress').html (Math.round ((dlBytes / totalBytes) * 100) + "%"):
                              $('#progress').html (Math.round (dlBytes / 1024) + "K");
                      }
                  }, 50); // Check the status every 50 miliseconds
              }
          },
          complete    : function ()
          {
              // Kill the download progress polling timer
              if (myTrigger)
                  clearInterval (myTrigger);
          }
      });
      </script>
      

      【讨论】:

        猜你喜欢
        • 2010-09-09
        • 1970-01-01
        • 1970-01-01
        • 2016-08-12
        • 2017-06-26
        • 1970-01-01
        • 2017-04-10
        • 2013-07-13
        • 1970-01-01
        相关资源
        最近更新 更多