17

Hi all I have this code:

function test()
{
    req = new XMLHttpRequest();
    req.upload.addEventListener("progress", updateProgress, false);
    req.addEventListener("readystatechange", updateProgress, false);
    req.addEventListener("error", uploadFailed, false);
    req.addEventListener("abort", uploadCanceled, false);

    var data = generateRandomData(currentPayloadId);
    totalSize = data.length;

    req.open("POST", "www.mydomain.com/upload.aspx");
    start = (new Date()).getTime();
    req.send(data);
}

function updateProgress(evt)
{
    if (evt.lengthComputable) {
        total = totalSize = evt.total;
        loaded = evt.loaded;
    }
    else {
        total = loaded = totalSize;
    }
}

Also, my server responds to the initial OPTIONS request for upload.aspx with 200 and the Access-Control-Allow-Origin: * and then the second request POST happens

Everything seems in place and it's working great on FireFox but on G Chrome the updateProgress handler is not getting called but only once and then the lengthComputable is false.

I needed the Access-Control-Allow-Origin: * because this is a cross-domain call, the script parent is a resource on a different server then the upload.aspx domain

Anyone can give me some clues, hints, help please? is this a known issue with G Chrome?

Thank you! Ova

erikvold
  • 15,988
  • 11
  • 54
  • 98
ovi
  • 460
  • 4
  • 18
  • 1
    Does this work when it is not CORS? If it does then raise a bug on http://crbug.com/new – Kinlan Apr 03 '12 at 18:35
  • for people looking around, the eval body of `func updateProgress` may be entirely skipped if the xhr progress event has set `evt.lengthComputable` to false. I'm not quite sure of what determines this behavior, but it seems to happen with one-chunk small exchanges in requests. You can easily check {in the same function} completion (only) by checking the event handlers `position` and `loaded` properties. (btw this syntax is not (most likely) compatible with the newest iterations of jquery.) – Cristian Cavalli Mar 20 '14 at 20:14
  • 1
    Since you are using an absolute URL, shouldn't it begin with: "http://"? – Scott Marcus Oct 28 '16 at 18:33
  • I have similar issue with progress event: https://stackoverflow.com/questions/48679979/xmlhttprequest-onprogress-event-function-has-different-behavior – sultan Mar 10 '18 at 14:15

5 Answers5

4

I think I have a solution for your problem
I don't know what is behind this function "generateRandomData()"

var data = generateRandomData(currentPayloadId)

It is working when I change into this:

var data = new FormData();
data.append("fileToUpload", document.getElementById('fileToUpload').files[0]);

Small explanation: You need manually to append to form data an file input form, where fileToUpload is <input type="file" name="fileToUpload" id="fileToUpload" />
And in your updateProgress function in IF part you can add something like this to track progress console.log(evt.total +" - "+ evt.loaded)
enter image description here

This is working in Google Chrome browser. I have tested in new browser version 57
I made for myself an upload progress form 4 years ago, which means that this code is working in old browser version too.

A whole code snippet will be looking like this

function test()
{
    req = new XMLHttpRequest();
    req.upload.addEventListener("progress", updateProgress, false);
    req.addEventListener("readystatechange", updateProgress, false);
    req.addEventListener("error", uploadFailed, false);
    req.addEventListener("abort", uploadCanceled, false);

    //var data = generateRandomData(currentPayloadId);
    var data = new FormData();
    data.append("fileToUpload", document.getElementById('fileToUpload').files[0]);
    totalSize = data.length;

    req.open("POST", "www.mydomain.com/upload.aspx");
    start = (new Date()).getTime();
    req.send(data);
}

function updateProgress(evt)
{
    if (evt.lengthComputable) {
        total = totalSize = evt.total;
        loaded = evt.loaded;
        console.log(evt.total +" - "+ evt.loaded)
    }
    else {
        total = loaded = totalSize;
    }
}
Nebojsa Nebojsa
  • 1,395
  • 1
  • 7
  • 19
1

I had this problem when the page your are loading doesn't contain a

  Content-Length: 12345

in the header, where 12345 is the length of the response in bytes. Without a length parameter, the progress function has nothing to work on.

Nathaniel
  • 88
  • 6
0

First, make sure that "www.example.com" is added to the manifest.json, like so:

manifest.json

 {
   ..
   "permissions": [
     "http://www.example.com/",
     "https://www.example.com/",
   ],
   ..
 }

Then I think your example should work.

For more information about using xhr in google chrome extensions the docs are here.

Also the CSP docs are worth taking a look at if what I provided above does not.

erikvold
  • 15,988
  • 11
  • 54
  • 98
0

This could simply be a compatibility issue with the XMLHttpRequest.upload property. It returns an XMLHttpRequestUpload object, but if you try find that object spec in MDN it doesn't exist so how do we know which browsers fully support it.

XMLHttpRequest.upload Compatability Compatability for the XMLHttpRequest.upload property

Have you tried listening for progress directly on the xhr:

req.addEventListener("progress", updateProgress, false);
R. McIntosh
  • 166
  • 4
0

I use jQuery for progress like that:

    $.ajax({
        url : furl,
        type : method,
        data : data,
        //...
        },
        xhr : function () {
            //upload Progress
            var xhr = $.ajaxSettings.xhr();
            if (xhr.upload) {
                    xhr.upload.addEventListener('progress', function (event) {
                        var percent = 0;
                        var position = event.loaded || event.position;
                        var total = event.total;
                        if (event.lengthComputable) {
                            percent = Math.ceil(position / total * 100);
                        }
                        //update progressbar
                        $(".progress-bar").css("width",  + percent + "%");
                        $(" .status").text(position + " / " + total + " (" + percent + "%)");
                    }, true);
            }
            return xhr;
        },
Dmitrii S.
  • 28
  • 3