Session Upload Progress with JQuery

2019-09-01 09:17发布

问题:

I'm attempting to convert this example which uses pure JavaScript to a JQuery equivalent.

The problem is that whenever I hit the upload button, it toggles the progress bar for the duration of the setTimeout function (1 second), then it disappears and displays "Done" having never shown me any actual progress.

I am using PHP > 5.4. I have session.upload_progress.enabled = On. I am uploading a huge file that I know should take several seconds to complete even locally.

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<script type="text/javascript" src="//code.jquery.com/jquery-latest.min.js"></script>
<style>
#progress_bar {
  border: solid 1px #000;
  height: 20px;
  width: 300px;
  display: none;
}
#bar_color {
  background-color: #006666;
  height: 20px;
  width: 0px;
}
</style>
<title>File Upload Progress Bar</title>
</head>
<body>

<div id="progress_bar">
  <div id="bar_color"></div>
</div>
<div id="upload_status"></div>

<form id="uploadForm" enctype="multipart/form-data">
<input type="hidden" name="<?php echo ini_get('session.upload_progress.name'); ?>" value="uploadForm" />
<input type="hidden" name="MAX_FILE_SIZE" value="9999999" />
<input type="file" name="file" /><br />
<input type="submit" value="Start Upload" />
</form>

</body>
</html>

JQuery:

<script>
$(document).ready(function () {
    var interval;

    // update status bar
    $("#uploadForm").submit(function(e) {
        e.preventDefault();

        $('#progress_bar').toggle();
        interval = setInterval(function() {
            $.ajax({
                cache: false,
                url: "status.php",
                type: "GET"
            })
            .done(function(response) {
                if (response) {
                    $('#bar_color').width(response + '%');
                    $('#upload_status').html(response + '%');

                    if (response < 100) {
                        setInterval(interval, 1000);
                    } else {
                        $('#progress_bar').toggle();
                        $('#bar_color').width(0 + 'px');
                        $('#upload_status').html('Done.');
                        clearInterval(interval);
                    }
                }
            });
        }, 1000);
    });
});
</script>

PHP:

<?php
session_start();

$key = ini_get('session.upload_progress.prefix') . 'uploadForm';
if (!empty($_SESSION[$key])) {
    $current = $_SESSION[$key]['bytes_processed'];
    $total = $_SESSION[$key]['content_length'];
    echo $current < $total ? ceil($current / $total * 100) : 100;
} else {
    echo 100;
}

Where am I going wrong?

回答1:

You have to upload the file with ajax and update the progress bar while it's uploading, not when it's done. http://jsfiddle.net/SwHf6/

$('input[type=file]').change(function() {
    var fd = new FormData();
    fd.append('file', $('input[type=file]').get(0).files[0]);

    $.ajax({
        url: '.',
        type: 'POST',
        processData: false,
        data: fd,
        xhr: function() {
            var xhr = $.ajaxSettings.xhr();
            xhr.upload.addEventListener('progress', function(ev) {
                $('.bar').css('width', (ev.loaded/(ev.total/100))+'%');
            }, false);

            return xhr;
        },
        beforeStart: function() {
            $('.bar').css('width', '0%');
        },
        success: function() {
            alert('done');
        }
    });
});