【问题标题】:Getting progress of PHP script called by jQuery post获取由 jQuery post 调用的 PHP 脚本的进度
【发布时间】:2014-02-25 18:26:29
【问题描述】:

我想定期检查 php 脚本的状态并将其显示在浏览器上。这是用于发布的jQuery。

$(document).ready(function() {
      $("#tempbut").click(function(event){
           $('#loader').show();
           $('#mainarea').hide('fast');

          $.post(
           "template.php",
           {
                guide : $('#guide').val(),
                title : $('#title').val()
           },
            function(data) {
                $('#mainarea').empty();
                $('#loader').fadeOut('slow');
                $('#mainarea').append(data);
                $('#mainarea').show('slow');
             }

          );
      });
   });

在 PHP 脚本(未发布)中,我回显诸如“构建请求...”、“发送请求...”之类的语句以通知用户进度。如果我不使用 jQuery post,我将能够在每次回显后使用 flush() 和 obflush() 显示状态。也许是因为回调等待脚本完全执行后才输出?

有没有办法修改现有的 jQuery .post 来做到这一点?我看到一些使用 .ajax 的示例,但不是 .post。

如果 .ajax 是执行此操作的唯一方法,我将如何修改此代码?

谢谢!

编辑: 跑起来了!希望有人会觉得这很有帮助。 (可以删除console.log)

test.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>TEST</title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge;chrome=1" />
    <script src="http://code.jquery.com/jquery-2.1.0.js"></script>
    <script>
        $.ajax({
            url: "test.php",
            xhrFields: {
                onprogress: function(e) {
                    console.log(e.target.responseText)
                    $("body").html(e.target.responseText)
                    if (e.lengthComputable) {
                        console.log(e.loaded / e.total * 100 + '%');
                    }
                }
            },
            success: function(text) {
                    console.log(text)
                    $("body").html(text+"<h1>done!</h1>")
            }
        });
    </script>
</head>
<body>
<div id="derp">TEST!</div>

</body>
</html>

test.php

<?php

for($i = 0; $i<20 ; $i++){
    sleep(1);
    echo $i."</br>";
    flush();
    ob_flush(); 
}
?>

【问题讨论】:

    标签: php jquery ajax polling


    【解决方案1】:

    post 是 ajax(type:post) 的快捷方式,没什么不同。

    要获得进度报告有一些方法。我现在最简单的方法是向同一页面发出 2 个 ajax 请求 1 以运行您的 php 脚本并将状态存储在会话中,另一个存储到不同的页面从会话中读取状态并将其打印给用户。

    更新:

    在 php 脚本完成之前,我的错误会话不会被记录下来。 您可以尝试将状态写入文件并像这样读取它:

    task.php

    for ($i = 0; $i < 10; $i++) {
        echo($i . "<br/>");
        file_put_contents('progress', $i);
        sleep(2);
    }
    

    progress.php

    if (file_exists('progress') && is_readable('progress'))
        echo file_get_contents('progress');
    else
        echo(-1);
    

    和脚本:

    <script>
        $(document).ready(function () {
            task();
            getProgress();
        });
        function task() {
            $.ajax({
                url: 'http://localhost/test/progress/task.php',
                success: function (data) {
                    console.log('Task is over :' + data);
                }
            });
        }
        function getProgress() {
            $.ajax({
                url: 'http://localhost/test/progress/progress.php',
                success: function (data) {
                    data = parseInt(data);
                    if (data != 9) {
                        console.log('progress :' + data);
                        setTimeout(function () {
                            getProgress();
                        }, 1000);
                    }
                }
            });
        }
    </script>
    

    但是是一个多用户环境,这会导致问题。

    所以你能做的最好的事情就是将状态存储在其中一个中:

    • 使用数据库
    • 使用内存缓存
    • 使用 APC

    【讨论】:

    • 我尝试了您的建议,但没有成功。我已经编辑了 OP 以反映我的尝试,请在有机会时看看。谢谢。
    • 感谢您解释您的方法。好像您正在使用文件来传输数据。我想尽量减少读/写并避免使用文件。我确实使用 xhrFields 和 onprogress 让它工作,并在 OP 上进行了编辑以反映它。希望它可以帮助别人!
    猜你喜欢
    • 1970-01-01
    • 2011-04-28
    • 2012-04-10
    • 2014-09-03
    • 1970-01-01
    • 1970-01-01
    • 2012-07-26
    • 2011-07-28
    • 1970-01-01
    相关资源
    最近更新 更多