2010-07-28 11 views
16

Sto provando la nuova funzionalità XMLHTTPRequestUpload per caricare alcuni file in uno script php, funziona in gran parte, l'upload inizia, ottengo la risposta finale ecc. sembra funzionare.Lo stato di caricamento XHR è al 100% dall'inizio

Osservando che il valore event.loaded - In firefox mi sembra di ottenere un valore casuale compreso tra 0 e la dimensione del file; in Chrome (dove lavoro principalmente) ottengo le dimensioni totali del file, anche se il readystate non ha raggiunto il '4' e la finestra Strumenti per gli sviluppatori mostra ancora il file da caricare?

Qualche idea?

Heres il mio codice:

var xhr = new XMLHttpRequest() 

xhr.upload.addEventListener('progress', function(event) { 
    if (event.lengthComputable) { 
     $('ajaxFeedbackDiv').innerHTML = event.loaded + '/' + event.total; 
    } 
}, false); 

xhr.onreadystatechange = function(event) { 
    if (event.target.readyState == 4) { 
     updateFileList(); 
    } 
}; 

xhr.open("POST", "_code/upload.php"); 
xhr.setRequestHeader("Cache-Control", "no-cache"); 
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 
xhr.setRequestHeader("X-File-Size", file.size); 
xhr.setRequestHeader("X-File-Type", file.type); 
xhr.setRequestHeader("Content-Type", "multipart/form-data"); 
xhr(file); 

Molte grazie

Ben

+0

Hai trovato qualche soluzione o soluzione per il problema? Al momento sto vivendo lo stesso, ma sembra dipendere dalla tua connessione di rete. Funziona come previsto in una posizione e salta al 100% dall'altra. – unclenorton

+3

Sto riscontrando lo stesso problema. È interessante notare che sembra che questo accada solo quando sono in esecuzione su localhost - quando lo distribuisco ai nostri server di sviluppo o di sviluppo, il valore caricato ritorna come ci si aspetterebbe. – brettjonesdev

risposta

16

Ho anche recentemente avuto qualche impostazione di un listener di eventi per gli eventi XHR onProgress difficoltà. Ho finito per la sua attuazione come una funzione anonima, che funziona a meraviglia:

xhr.upload.onprogress = function(evt) 
{ 
    if (evt.lengthComputable) 
    { 
     var percentComplete = parseInt((evt.loaded/evt.total) * 100); 
     console.log("Upload: " + percentComplete + "% complete") 
    } 
}; 

mi sono imbattuto in un sacco di altri trucchi lungo la strada, però, quindi è molto probabile che uno di questi era inciampare il mio listener di eventi . L'unica altra differenza tra quello che hai e la mia configurazione è che sto usando xhr.sendAsBinary().

0

Mi sono imbattuto in un problema simile me stesso, in cui il mio gestore di eventi funzione per eventi progress su XMLHttpRequest è stato eseguito solo una volta - al termine del caricamento.

La causa del problema è stata semplice: in Google Chrome (probabilmente anche altri browser, non ho eseguito il test), l'evento progress verrà attivato in successione solo se il caricamento è stato eseguito per un secondo o due. In altre parole, se il tuo caricamento termina rapidamente, probabilmente otterrai un evento al 100% progress.

Ecco un esempio di codice di cui progress evento si attiva solo una volta al 100% completa (https://jsfiddle.net/qahs40r6/): uscita

$.ajax({ 
    xhr: function() 
    { 
    var xhr = new window.XMLHttpRequest(); 
    //Upload progress 
    xhr.upload.addEventListener("progress", function(evt){ 
     if (evt.lengthComputable) { 
     var percentComplete = evt.loaded/evt.total; 
     console.log("Upload ", Math.round(percentComplete*100) + "% complete."); 
     } 
    }, false); 
    return xhr; 
    }, 
    type: 'POST', 
    url: "/echo/json/", 
    data: {json: JSON.stringify(new Array(20000))} 
}); 

Console:

Upload 100% complete. 

Ma se si aggiunge un extra pari a zero per le dimensioni della matrice (aumentando le dimensioni del carico utile di un fattore di 10 - https://jsfiddle.net/qahs40r6/1/):

$.ajax({ 
    xhr: function() 
    { 
    var xhr = new window.XMLHttpRequest(); 
    //Upload progress 
    xhr.upload.addEventListener("progress", function(evt){ 
     if (evt.lengthComputable) { 
     var percentComplete = evt.loaded/evt.total; 
     console.log("Upload ", Math.round(percentComplete*100) + "% complete."); 
     } 
    }, false); 
    return xhr; 
    }, 
    type: 'POST', 
    url: "/echo/json/", 
    data: {json: JSON.stringify(new Array(200000))} 
}); 

Quindi si ottiene la progressione normale di progress eventi:

Upload 8% complete. 
Upload 9% complete. 
Upload 19% complete. 
Upload 39% complete. 
Upload 50% complete. 
Upload 81% complete. 
Upload 85% complete. 
Upload 89% complete. 
Upload 100% complete. 

Questo comportamento dipende dalla velocità della connessione a Internet è, così il vostro chilometraggio può variare. Ad esempio, se utilizzi il primo esempio e utilizzi gli Strumenti per sviluppatori di Chrome per rallentare la connessione a un "3G lento" simulato, vedrai la serie di eventi progress.

Analogamente, se si sta sviluppando localmente e si caricano dati su un server Web locale, è probabile che non vengano mai visualizzati eventi progress perché il caricamento verrà completato immediatamente. Questo è probabilmente ciò che @brettjonesdev stava vedendo nelle distribuzioni di localhost rispetto a produzioni remote.

Problemi correlati