在php,ajax或javascript中加载进度?

时间:2009-04-16 00:46:17

标签: php javascript ajax

当系统仍然在服务器端获取数据时,任何人都知道如何在客户端显示已完成%的加载进度。

例如,当我在客户端按“确定”按钮时,它会调用服务器端从数据库中收集数据,整个过程可能需要2到3分钟。如何在客户端显示加载进度(大约有多少%的loding已经完成)?

我怎么能在php,ajax或javascript中做到这一点?

6 个答案:

答案 0 :(得分:3)

我需要做同样的事情 - 跟踪Ajax数据下载进度 - 所以我会发布一个我用过的解决方案,以防有人碰到这个帖子:

var req = new XMLHttpRequest();

req.addEventListener("progress", onUpdateProgress, false);
req.addEventListener("load", onTransferComplete, false);
req.addEventListener("error", onTransferFailed, false);
req.addEventListener("abort", onTransferAborted, false);

req.open("GET", ..., true);

...

req.send()

function onUpdateProgress(e) {
  if (e.lengthComputable) {
    var percent_complete = e.loaded/e.total;
    document.getElementById("progressMessage").value = Math.round(percentComplete*100) +"% [ " + Math.round(e.loaded / 1000) + " KB ]";
    ...
  } else {
    // Length not known, to avoid division by zero
  }
}

function onTransferComplete(e) { ... }

function onTransferFailed(e)   { ... }

function onTransferAborted(e)  { ... }

答案 1 :(得分:2)

点击“确定”按钮后,您可以开始获取服务器端的数据并保持会话中的百分比。

这样,客户端你可以通过AJAX向另一个PHP脚本发出请求,返回加载的百分比。

最终会得到2个服务器端脚本(一个用于获取数据,另一个用于获取百分比)和一个AJAX请求客户端。

我认为这是一个简单的解决方案,应该做得很好。

答案 2 :(得分:2)

这并不容易。如果ajax调用开始处理,你可以做一个chunked / multipart响应(这就是大多数dhtml聊天的实现方式)。谷歌为“COMET”。

基本上就是这样的:

  1. client:请求启动长时间运行的ajax调用
  2. 服务器:启动长时间运行的操作,echo 0%,flush();(无脚本终止)
  3. 客户端:收到带有刷新内容的响应(特殊回调),显示值,但连接保持打开状态!
  4. 服务器:在x操作后计算百分比echoflush();
  5. 客户:请参阅#3
  6. 服务器:如果脚本已完成,请终止
  7. client:脚本结束的正常事件/回调。显示100%,打开下一页
  8. 我曾经(当异步javascript仍然是新的!)编写了一个小小的演示......它现在有点失效,但异步部分仍然有效。你可以在这里找到它:http://wehrlos.strain.at/httpreq/client.html

    使用的javascript客户端代码

    function asSendSyncMulti() {
        var httpReq = new XMLHttpRequest();
    
        showMessage( 'Sending Sync Multipart ' + (++this.reqCount)  );
    
        // Sync - wait until data arrives
        httpReq.multipart   = true;     
        httpReq.open( 'GET', 'server.php?multipart=true&c=' + (this.reqCount), false );
        httpReq.onload = showReq;
        httpReq.send( null );
    }
    
    function showReq( event ) {
        if ( event.target.readyState == 4 ) {
            showMessage( 'Data arrives: ' + event.target.responseText );
        }
        else {
            alert( 'an error occured: ' + event.target.readyState );
        }
    }
    

    多部分的服务器端php代码:

    <?php
    
        $c = $_GET[ 'c' ];
    
            header('Content-type: multipart/x-mixed-replace;boundary="rn9012"');
    
            sleep( 1 );
    
            print "--rn9012\n";
            print "Content-type: application/xml\n\n";
            print "<?xml version='1.0'?>\n";
            print "<content>Multipart: First Part of Request " . $c . "</content>\n";
            print "--rn9012\n";
            flush();
    
            sleep( 3 );
    
            print "Content-type: application/xml\n\n";
            print "<?xml version='1.0'?>\n";
            print "<content>Multipart: Second Part of Request " . $c . "</content>\n";
            print "--rn9012--\n";
    ?>
    

    这只不过是一个可能的方向推动。不符合HTML标准或交叉浏览。使用json而不是xml。

    在服务器端,必须关闭输出缓存(例如压缩),否则flush();将不会执行任何操作。并且--rn9012应该是您输出的数据中永远不会出现的内容(如果您只显示进度但仍然是unlikley)。

答案 3 :(得分:0)

我通过分页结果来做到这一点。

第一个请求是获取计数。然后将请求分解为一组组。 然后开始一次请求一组。

例如:如果要返回100条记录,我将它们分成10组。 然后我可以很容易地显示10%... 20%......等等。

无论如何我都不知道这样做。

答案 4 :(得分:0)

jQuery可以在ajax请求运行时显示启动画面(div)。这可以使用.ajaxStart和.ajaxEnd(或.ajaxStop)为每个请求完成,或者更复杂的方法是使用Dojo的dojo.io.bind或遵循下面的Periodic Refresh Pattern。

Periodic Refresh

答案 5 :(得分:0)

的multipart / X - 混合取代;使用flush应该在无状态负载平衡环境中工作。 依赖于定期GET请求检查进度的方法在后续请求可能转到不同后端的环境中将不会成功。