it-swarm.com.de

Fortschrittsbalken beim Hochladen großer Dateien mit XMLHttpRequest

Ich versuche, einige große Dateien mit XMLHttpRequest und file.slice auf den Server hochzuladen.
Ich habe es mit Hilfe von Dokumentationen und anderen Links geschafft. 
Da das Hochladen einer großen Datei ein langwieriger Job ist, möchte ich dem Benutzer eine Fortschrittsleiste zur Verfügung stellen.
Nach einigen weiteren Lesungen bin ich auf ein Beispiel gestoßen, das theoretisch genau das macht, was ich brauche. 
Durch die Verwendung des Beispielcodes und der Anpassung an meine Bedürfnisse bin ich erreicht

var upload =
{
blobs: [],
pageName: '',
bytesPerChunk: 20 * 1024 * 1024,
currentChunk: 0,
loaded: 0,
total: 0,
file: null,
fileName: "",

uploadChunk: function (blob, fileName, fileType) {
    var xhr = new XMLHttpRequest();

    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
            if (xhr.responseText) {
                // alert(xhr.responseText);
            }
        }
    };

    xhr.addEventListener("load", function (evt) {
        $("#dvProgressPrcent").html("100%");
        $get('dvProgress').style.width = '100%';
    }, false);

    xhr.addEventListener("progress", function (evt) {
        if (evt.lengthComputable) {
            var progress = Math.ceil(((upload.loaded + evt.loaded) / upload.total) * 100);
            $("#dvProgressPrcent").html(progress + "%");
            $get('dvProgress').style.width = progress + '%';
        }
    }, false);

    xhr.upload.addEventListener("progress", function (evt) {
        if (evt.lengthComputable) {
            var progress = Math.ceil(((upload.loaded + evt.loaded) / upload.total) * 100);
            $("#dvProgressPrcent").html(progress + "%");
            $get('dvProgress').style.width = progress + '%';
        }
    }, false);

    xhr.open('POST', upload.pageName, false);

    xhr.setRequestHeader("Content-Type", "multipart/form-data");
    xhr.setRequestHeader("X-File-Name", fileName);
    xhr.setRequestHeader("X-File-Type", fileType);
    xhr.send(blob);
},
upload: function (file) {
    var start = 0;
    var end = 0;
    var size = file.size;

    var date = new Date();
    upload.fileName = date.format("dd.MM.yyyy_HH.mm.ss") + "_" + file.name;

    upload.loaded = 0;
    upload.total = file.size;

    while (start < size) {
        end = start + upload.bytesPerChunk;
        if (end > size) {
            end = size;
        }

        var blob = file.slice(start, end);
        upload.uploadChunk(blob, upload.fileName, file.type);
        start = end;
        upload.loaded += start;
    }

    return upload.fileName;
}
};

Der Anruf ist wie (ohne die Validierungen)

upload.upload(document.getElementById("#upload").files[0]);

Mein Problem ist, dass das Fortschrittsereignis nicht ausgelöst wird. 
Ich habe xhr.addEventListener und mit xhr.upload.addEventListener (jeweils zu einem Zeitpunkt und beide gleichzeitig) für das Fortschrittsereignis ausprobiert, aber es wird niemals ausgelöst. Die onreadystatechange- und load-Ereignisse werden problemlos ausgelöst.

Ich würde mich sehr über die Hilfe bei dem, was ich falsch mache, sehr freuen

Aktualisieren
Nach vielen Versuchen habe ich es geschafft, einen Fortschritt zu simulieren, aber ich bin auf ein anderes Problem gestoßen: Die Benutzeroberfläche von Chrome wird während des Uploads nicht aktualisiert.
Der Code sieht jetzt so aus

var upload =
{
    pageName: '',
    bytesPerChunk: 20 * 1024 * 1024,
    loaded: 0,
    total: 0,
    file: null,
    fileName: "",

    uploadFile: function () {
        var size = upload.file.size;

        if (upload.loaded > size) return;

        var end = upload.loaded + upload.bytesPerChunk;
        if (end > size) { end = size; }

        var blob = upload.file.slice(upload.loaded, end);

        var xhr = new XMLHttpRequest();

        xhr.open('POST', upload.pageName, false);

        xhr.setRequestHeader("Content-Type", "multipart/form-data");
        xhr.setRequestHeader("X-File-Name", upload.fileName);
        xhr.setRequestHeader("X-File-Type", upload.file.type);

        xhr.send(blob);

        upload.loaded += upload.bytesPerChunk;

        setTimeout(upload.updateProgress, 100);
        setTimeout(upload.uploadFile, 100);
    },
    upload: function (file) {
        upload.file = file;

        var date = new Date();
        upload.fileName = date.format("dd.MM.yyyy_HH.mm.ss") + "_" + file.name;

        upload.loaded = 0;
        upload.total = file.size;

        setTimeout(upload.uploadFile, 100);


        return upload.fileName;
    },
    updateProgress: function () {
        var progress = Math.ceil(((upload.loaded) / upload.total) * 100);
        if (progress > 100) progress = 100;

        $("#dvProgressPrcent").html(progress + "%");
        $get('dvProgress').style.width = progress + '%';
    }
};


Update 2
Ich habe es geschafft, es zu reparieren und eine Fortschrittsleiste zu simulieren, die auch in Chrom funktioniert.
Ich habe das vorherige Codebeispiel mit dem funktionierenden aktualisiert.
Sie können die Leiste häufiger "aktualisieren", indem Sie die Größe des jeweils hochgeladenen Blocks reduzieren Tahnk Sie für Ihre Hilfe

13
Cioby

Wie in https://stackoverflow.com/a/3694435/460368 angegeben, können Sie Folgendes tun:

if(xhr.upload)
     xhr.upload.onprogress=upload.updateProgress;

und

updateProgress: function updateProgress(evt) 
{
   if (evt.lengthComputable) {
       var progress = Math.ceil(((upload.loaded + evt.loaded) / upload.total) * 100);
       $("#dvProgressPrcent").html(progress + "%");
       $get('dvProgress').style.width = progress + '%';
   }
}
5
Shikiryu

Es gibt meine Lösung:

function addImages(id)
{


var files= $("#files").prop("files");
var file = files[loopGallery];
var cList= files.length;

var fd = new FormData();

fd.append("file", file);
fd.append("galerie", id);


var xhr = new XMLHttpRequest();

xhr.open("POST", "moduls/galerie/uploadimages.php", true);

xhr.upload.onprogress = function(e)
{

var percentComplete = Math.ceil((e.loaded / e.total) * 100);

$("#progress").css("display","");

$("#progressText").text((loopGallery+1)+" z "+cList);
$("#progressBar").css("width",percentComplete+"%");

};


xhr.onload = function()
{

if(this.status == 200)
{
    $("#progressObsah").load("moduls/galerie/showimages.php?ids="+id);

    if((loopGallery+1) == cList)
    {
        loopGallery = 0;

    }
    else
    {
    $("#progressBar").css("width", "0%");   
loopGallery++;
addImages(id);
}

};

};

if(cList < 1)
{

}
else
{
xhr.send(fd);
}


}
1
koca79331