1

I need advice on my ajax progress bar while executing a long PHP script treating pictures. I know there are plenty of questions on stackoverflow already like

Most of the examples I see are using the file size to calculate the progress. But in my case I would like to calculate percentage based on images_treated / total_images.

So I still can't make this work as I want.

In JS bellow I commented the not working progress function I took from another question and dataType: 'json' for tests but I would prefer if I can still use a JSON return.

Questions

  1. The console.log() will only log once - when the full script is done. Am I doing it wrong?
  2. What should I write to replace the comment?
  3. in some answers, the PHP headers are set to header('Content-Type: application/octet-stream'); is it mandatory or just nicer?

Javascript:

        $.ajax(
        {
            type: 'GET',
            // dataType: 'json',
            url: formAction,
            data: 'addImagesToArticle',
            cache: false,
            xhr: function()
            {
                var xhr = new window.XMLHttpRequest();

                // Download progress.
                xhr.addEventListener("progress", function(e)
                {
                    console.log(e);
                    // I saw this piece of code from another question it is supposed to work... Maybe my PHP?
                    /*var lines = e.currentTarget.response.split("\n");
                    var progress = lines.length ? lines[lines.length-1] : 0;

                    $('#progress').text(progress);*/
                }, false);
               return xhr;
            }
        });

My PHP is quite big so I just explain quickly: in the loop on pics I have variables $images_treated and $total_images. After the loop, a summary is returned to JS via JSON in an object like {error: bool, message: string, ...} so if there is a way to make the progress work without echoing but setting a JSON variable that would be perfect!

Thank you for your help!

[EDIT] to add context details.

I want to use this in an admin side, in an article edition with a WYSIWYG, I have dropzone taking care of my multiple images uploads.

then I see the preview of images while each image is put in temp folder on server. I can then remove some images if needed and once all images are definitive, i click a button that will process them for resizing 2 sizes and inject figure tags with img in the article WYSIWYG editor.

26
  • An AJAX request and the work done on the server to serve that request is a treated single entity. This means that you cannot know what work the server is doing simply from the progress event, only how much data has been sent/received. If you want to know the progress in the steps the server has taken you would need to code the server so that it stores it's last completed task on an endpoint which is reachable from a second AJAX request which you then call at intervals while the main request is running. Commented Jul 9, 2016 at 17:44
  • Yes if I understand you I need a second php to send progress, so the progress can be stored in session if needed its fine. But then how do I question both PHP scripts from one AJAX in JS file? Commented Jul 9, 2016 at 17:48
  • I think that what you are trying to achieve is slightly different from your approach. Here you can find a question about this topic. You can print from the server side the status of the processing. Hope it helps. Commented Jul 9, 2016 at 17:48
  • @antoni you can't do it in a single AJAX request, you need to use at least 2. That's why this method is considered very outdated (note the guide linked above is from over 5 years ago) and it will put quite a lot of extra load on your server as you're exponentially increasing the number of requests made to the server if you follow this pattern Commented Jul 9, 2016 at 17:51
  • 1
    @antoni, don't trust CMSs, they do very bad things just to have glittery UIs and mislead developers. Commented Jul 9, 2016 at 18:08

1 Answer 1

1

Waw I found a solution!

I am happy to discover that new thing I did not know about PHP and share with people who also don't know (in step 3 bellow)!

@riccardo was right talking about socket - which I don't know so well - but I did not need to go that far.

So I had multiple things to solve in my case before being able to get closer of my goal.

  1. not using xhr.addEventListener("progress"... but a second ajax call in a timer: it will also be lighter-weight in resource consumption.

  2. rather than using a timer like setInterval or setTimeout - as requests are async it may come in unwanted order - use a recursive call in callback of first call like:

    function trackProgress()
    {
        $.getJSON('create-a-new-page.html', 'ajaxTrackProgress=1', function(response)
        {
            var progress = response.progress;
            $('#progress').text(progress);
    
            if (progress < 100) trackProgress();
        });
    }
    
  3. then realize that my second script call is delayed by first script still running? yes. So the key here is session_write_close()! I could dig in this way thanks to this good post: https://stackoverflow.com/a/1430921/2012407

and I posted a very simple example here to reply to another question: https://stackoverflow.com/a/38334673/2012407

Thank you for all your help in comments guys, it led me to this solution. ;)

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.