2010-07-28 20 views
16

Estoy probando la nueva característica XMLHTTPRequestUpload para cargar algunos archivos a un script php, en su mayoría funciona bien, la carga comienza, obtengo la respuesta de finalización, etc., pero el progreso no Parece que funcionaEl progreso de carga de XHR es 100% desde el inicio

Buscando que el valor de event.loaded - En Firefox me parece obtener un valor aleatorio entre 0 y el tamaño del archivo; en Chrome (donde trabajo en su mayoría) obtengo el tamaño total del archivo, aunque el estado preparado no ha alcanzado el '4' y la ventana Herramientas del desarrollador todavía muestra el archivo que se va a cargar?

¿Alguna idea?

Aquí está mi código:

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); 

Muchas gracias

Ben

+0

¿Ha encontrado alguna solución o solución para el problema? Actualmente estoy experimentando lo mismo, pero parece depender de tu conexión de red. Funciona como se esperaba en una ubicación y salta al 100% de la otra. – unclenorton

+3

Estoy experimentando el mismo problema. Curiosamente, parece que esto solo me sucede cuando estoy ejecutando en localhost: cuando despliego a nuestros servidores de desarrollo o prod, el valor cargado vuelve como era de esperar. – brettjonesdev

Respuesta

16

También recientemente tuvo algunas dificultades para el establecimiento de un detector de eventos para eventos XHR onProgress. Terminé implementarlo como una función anónima, que funciona de maravilla:

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

me encontré con un mucho de otros aspectos críticos a lo largo del camino, sin embargo, lo que es muy probable que uno de ellos fue tropezando con mi detector de eventos . La única otra diferencia entre lo que tienes allí y mi configuración es que estoy usando xhr.sendAsBinary().

0

Me encontré con un problema similar, donde mi función de controlador de eventos para progress eventos en XMLHttpRequest se ejecutó solo una vez, cuando se completó la carga.

La causa del problema terminó siendo simple: en Google Chrome (posiblemente otros navegadores también, no probé), el evento progress solo se activará sucesivamente si la carga se ha estado ejecutando durante uno o dos segundos. En otras palabras, si su carga finaliza rápidamente, es probable que obtenga un evento 100% progress.

He aquí un ejemplo de código cuya progress evento sólo se activa una vez al 100% completo (https://jsfiddle.net/qahs40r6/): salida

$.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))} 
}); 

Consola:

Upload 100% complete. 

Pero si se añade un extra de cero al tamaño de la matriz (aumentando el tamaño de la carga útil en un factor de 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))} 
}); 

se obtiene la progresión normal de progress eventos:

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. 

Este comportamiento depende de la velocidad de su conexión a Internet es, por lo que su kilometraje puede variar. Por ejemplo, si toma el primer ejemplo y usa las herramientas de desarrollo de Chrome para ralentizar su conexión a un "3G lento" simulado, verá la serie de eventos progress.

Del mismo modo, si está desarrollando localmente y cargando datos a un servidor web local, probablemente nunca verá los eventos progress porque la carga finalizará instantáneamente. Probablemente, esto fue lo que @brettjonesdev estaba viendo en las implementaciones localhost frente a las prod remotas.

Cuestiones relacionadas