JQuery ProgressBar - загружает все сразу - PullRequest
5 голосов
/ 02 августа 2011

Я хотел бы иметь индикатор выполнения jQuery, который обновляется в зависимости от состояния запроса на стороне сервера. Я основываю этот код на этом уроке , но он использует загрузчик файлов в качестве своей базы (так же, как этот вопрос). Я не могу заставить его работать так же без загрузки файла. Проблема в том, что индикатор выполнения обновляется только после выполнения process.php. Вместо того, чтобы асинхронно запрашивать обновленную информацию о прогрессе, он ожидает завершения всего процесса. Я вижу только данные: данные оповещения один раз.

Есть идеи?

Веб-сайт:

<form id="upload-form" action='process.php' method="post" target="upload-frame">
<input type="hidden" id="uid" name="UPLOAD_IDENTIFIER" value="<?php echo $uid; ?>" >
<input type="submit" value="Submit" />
</form>

<div id="progressbar"></div>

<iframe id="upload-frame" name="upload-frame" style="display:none"></iframe>

Process.php - вызывается при отправке формы

<?php
session_start();
$varArray=array(1,2,3,4);
$_SESSION['total']=count($varArray);

foreach($varArray as $val){
    $_SESSION['current']=$val;
    sleep(2);
}
?>

Javascript

$(document).ready(function() {
    var started = false;// This flag determines if the upload has started
    $(function() {
        // Start progress tracking when the form is submitted
        $('#upload-form').submit(function() {
            $('#progressbar').progressbar();// Initialize the jQuery UI plugin

            // We know the upload is complete when the frame loads
            $('#upload-frame').load(function() {
                // This is to prevent infinite loop
                // in case the upload is too fast
                started = true;
                // Do whatever you want when upload is complete
                alert('Upload Complete!');
            });

            // Start updating progress after a 1 second delay
            setTimeout(function() {
                // We pass the upload identifier to our function
                updateProgress($('#uid').val());
            }, 1000);
        });
    });

    function updateProgress(id) {
        var time = new Date().getTime();
        // Make a GET request to the server
        // Pass our upload identifier as a parameter
        // Also pass current time to prevent caching
        $.ajax({
            url: 'getProgress.php',
            type: "GET",
            cache: false,
            data: {'uid':id}, 
            dataType: 'text',
            success: function(data){
                alert("data: " + data);
                var progress = parseInt(data, 10);
                if (progress < 100 || !started) {
                    // Determine if upload has started
                    started = progress < 100;
                    // If we aren't done or started, update again
                    updateProgress(id);
                }
                // Update the progress bar percentage
                // But only if we have started
                started && $('#progressbar').progressbar('value', progress);
            }
        });
    }
}(jQuery));

getProgress.php - вызывается запросом ajax:

<?php
session_start();
if (isset($_REQUEST['uid'])) {
    if (isset($_SESSION['total']) && isset($_SESSION['current'])) {
        // Fetch the upload progress data
        $total = $_SESSION['total'];
        $current = $_SESSION['current'];
        // Calculate the current percentage
        $percent_done = round($current/$total*100);
        echo $percent_done;
    }else{
        echo 100;// If there is no data, assume it's done
    }
}
?>

1 Ответ

7 голосов
/ 02 августа 2011

AFAIK, PHP-сессии на самом деле синхронны.Это означает, что сценарий Process.php блокирует выполнение сценария getProgress.php до тех пор, пока Process.php не будет выполнен с сеансом.

Итак, что происходит:

  1. Process.phpзапускается и вызывает session_start ()
  2. Сервер передает управление сеансом для session_start ()
  3. getProcess.php запускается и вызывает session_start ()
  4. Сервер блокирует getProcess.php до тех пор, покасеанс не используется.
  5. Process.php завершает и закрывает сеанс.
  6. Сервер возобновляет getProcess.php и дает ему контроль над сеансом.
  7. getProcess.php теперь видитчто процесс завершен.

См. http://www.php.net/manual/en/function.session-write-close.php.

Данные сеанса обычно сохраняются после завершения вашего сценария без необходимости вызывать session_write_close (), но как данные сеансазаблокирован для предотвращения одновременной записи, только один сценарий может работать в сеансе в любое время.[...]

Я не тестировал следующий код, так как в данный момент у меня нет доступа к серверу, но я думаю, что он должен работать:

<?php
$varArray=array(1,2,3,4);
session_start();
$_SESSION['total']=count($varArray);
session_write_close ();

foreach($varArray as $val){
    session_start();
    $_SESSION['current']=$val;
    session_write_close ();
    sleep(2);
}
?>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...