从PHP脚本获取XMLHttpRequest进度

时间:2010-10-21 19:00:10

标签: php javascript xmlhttprequest

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

对此的答案可能就像“不可能”一样简单,因为现在看起来就是这样。但总结一下:如何监控正在运行的脚本(php)和XMLHttpRequest的进度?

4 个答案:

答案 0 :(得分:2)

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

我编写了这段代码来确定几年前在XHR操作中传输的数据的百分比,所以我为它没有反映我从那时起已经获得的编码经验多年而道歉。我几乎肯定不会这样写它!尽管如此,我仍然设法将其捕获,并希望它对您有用。

在编写本文时,IE7是可用的最新版资源管理器,我记得代码不起作用,因此它包含防止它在IE下初始化的代码。我从来没有在版本8或版本9的测试版中尝试过这个代码,它确实可以在这些版本中使用,但我不能保证它。如果你能在新版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>

答案 1 :(得分: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脚本。

答案 2 :(得分:0)

在某些浏览器(firefox for one)中,onreadystatechange with readyState 3(即加载)被多次调用,因此可以监视下载进度。

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

然而,Internet Explorer(至少对于IE7,后来不确定)不支持这一点,查询readyState 3的responseText或responseBody是一个错误。我也听说IE只调用onreadystatechange 一次使用readyState 3会使你的目的无用,但我建议你测试一下。

答案 3 :(得分:0)

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

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

使用带定时器的第二个ajax请求按SID + UID轮询进度。

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