2013-04-12 15 views
12

Ich versuche, einige große Dateien mit XMLHttpRequest und file.slice auf den Server hochzuladen.
Ich habe es geschafft, dies mit Hilfe von Dokumentationen und anderen verschiedenen Links zu tun.
Da das Hochladen großer Dateien ein längerer Job ist, möchte ich dem Benutzer einen Fortschrittsbalken bereitstellen.
Nach ein paar weiteren Lesungen bin ich auf eine example gestoßen, die theoretisch genau das tut, was ich brauche.
Durch den Beispielcode zu nehmen und es auf meine Bedürfnisse anzupassen erreicht iFortschrittsbalken beim Hochladen großer Dateien mit XMLHttpRequest

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 Aufruf ist wie (ohne die Validierungen)

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

Mein Problem ist, dass der Fortschritt Ereignis nicht ausgelöst.
Ich habe versucht xhr.addEventListener und mit xhr.upload.addEventListener (jeweils gleichzeitig und beide gleichzeitig) für das Fortschrittsereignis, aber es wird nie ausgelöst. Die Ereignisse "onreadystatechange" und "load" werden problemlos ausgelöst.

würde ich stark mit Hilfe schätzen, was ich falsch

aktualisiert
i verwalten haben Nach vielen Versuchen machte einen Fortschritt zu simulieren, aber ich habe in ein anderes Problem lautet: Chrome UI wird nicht während der Aktualisierung der Upload
Der Code sieht wie folgt nun

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 beheben und einen Fortschrittsbalken zu simulieren, die auch in Chrom funktioniert.
Ich habe das vorherige Codebeispiel mit dem, das funktioniert, aktualisiert.
Sie können die Bar machen ‚Aktualisieren‘ häufiger von der Größe des zu einem Zeitpunkt hochgeladen chunk reduziert tahnk Sie für Ihre Hilfe

+0

Verwenden Sie eine Funktion, um 'document.getElementById'-Aufrufe zu verkürzen? Es sieht so aus, als würde '$ get() 'es tun, aber ich sehe es nirgends definiert. – user1091949

+0

ja. Aber ich denke nicht, dass das das Problem ist. es funktioniert gut in der load-Ereignis und setzt es auf 100% – Cioby

+0

@Cioby könnten Sie eine JSFiddle Ihrer Lösung hochladen? – frogbandit

Antwort

3

Wie in https://stackoverflow.com/a/3694435/460368 erwähnt, könnten Sie 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 + '%'; 
    } 
} 
+1

Das Fortschrittsereignis wird immer noch nicht ausgelöst. – Cioby

+0

@Cioby Haben Sie versucht, es asynchron zu machen? 'xhr.open ('POST', upload.pageName, true);' http://www.w3.org/TR/XMLHttpRequest/#the-open()-method – Shikiryu

+0

@Cioby und hast du versucht http: // stackoverflow.com/a/4943774/460368? – Shikiryu

0

Es ist 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); 
} 


} 
Verwandte Themen