1

I am sending formdata to PHP using ajax.upload for upload file to Google cloud storage

Javascript:

 var ajax = new XMLHttpRequest();

//PROGRESS HANDLER
ajax.upload.addEventListener("progress", function(event) {
  var percent = ((event.loaded / event.total) * 100);
  console.log(Math.round(percent) + "% uploading... please wait");
}, false);

//COMPLETE HANDLER
ajax.addEventListener("load", function(event) {
  console.log(event.target.responseText);  
}, false);

//ERROR HANDLER
ajax.addEventListener("error", function(event) {
  console.log("Upload Failed");  
}, false);

//ABORT HANDLER
ajax.addEventListener("abort", function(event) {
  console.log("Upload Aborted");  
}, false);

ajax.open("POST", "api/storage.php");
ajax.send(formdata);

PHP:

    $_SESSION['storedBytes'] = 0;
    $_SESSION['fileSize'] = $file["size"];

    $uploader = $bucket->getResumableUploader(
      fopen($fileTmpLoc, 'r'),
      [
              'predefinedAcl' => 'publicRead',
              'name' => $_POST['uniqueName'],
              'resumable' => true,
              'chunkSize' => 262144,
              'uploadProgressCallback' => 'uploadProgress'
          ]
    );

    try {
        $object = $uploader->upload();
    } catch (GoogleException $ex) {
        $resumeUri = $uploader->getResumeUri();
        $object = $uploader->resume($resumeUri);
    }

function uploadProgress($storedBytes)
{
    if (isset($_SESSION['storedBytes'])) {
        $_SESSION['storedBytes'] += $storedBytes;
    } else {
        $_SESSION['storedBytes'] = $storedBytes;
    }
    $storedBytes = $_SESSION['storedBytes'];
    $totalSize = $_SESSION['fileSize'];
    $_SESSION['progress'] = ($storedBytes*100)/$totalSize;
    echo "Progress ".$_SESSION['progress'];
}

And i receive the correct progress value in uploadProgress function but how to send this value to ajax request response asynchronously or how to show progress in this situation.

2
  • Possible duplicate of PHP Ajax Upload Progress Bar Commented Sep 26, 2018 at 19:02
  • I would consider using Promises and Deferreds in your ajax calls. I will try to provide an example as soon as possible. Commented Sep 26, 2018 at 19:16

1 Answer 1

0

I would use promises in your javascript ajax calls. A jQuery example would be something like this:

// gets the state of the upload from the PHP server.
var getProgress = function(phpUrlForProgress){
    return $.ajax({
        url: phpUrlForProgress,
        type: 'get'
    });
};

var keepCheckingProgress = function(phpUrlForProgress){
    var deferred   = $.Deferred();
    var intervalID = setInterval(function(){
        getProgress(phpUrlForProgress).done(function(response){
            console.log(response); // see what the response looks like.

            // you might need to parse the response into JSON before your if() statement.
            if(response.percentComplete === 100) {// You are done with the upload
                clearInterval(intervalID); // stops the setInterval loop;
                deferred.resolve(response);
            } else {
                // some code to display a progress bar or whatever.
            }
        });
    }, 3000);// setInterval function repeats every 3 seconds until cleared.

    return deferred.promise();     
};

// initiates the upload.
$.ajax({
    url: phpUrlForUpload,
    type: 'post'
    data: formdata
});

// now start checking for upload progress.
var finished = keepCheckingProgress();

$.when(finished).then(function(){
    // do something now that the upload is 100% done
}); 

Please note that I have not had a chance to test this code for bugs or errors, it is just to give you an idea.

Basically Promises are a way to bring some order of operations to Javascript, which is asynchronous. It is a way of saying, when this task finishes, do some other task.

jQuery I believe uses a slightly different Promise implementation than other promise libraries. A general primer on promises can be found here.

Sign up to request clarification or add additional context in comments.

2 Comments

not success. Because keepCheckingProgress is called after upload is completed. It's not asynchronous.
ok, I will fixed it. By moving the keepCheckingProgress call outside of the .done() part of the ajax call that initiates the upload, it will now fire immediatedly after the upload, without waiting for the ajax call to get a response.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.