example - ¿Se puede agregar la funcionalidad onprogress a jQuery.ajax() usando xhrFields?
jquery ajax example (3)
Debe agregar un controlador de eventos a la solicitud antes de que se envíe. jQuery.ajax permite esto a través de la propiedad ''beforeSend'' http://api.jquery.com/jQuery.ajax/
por ejemplo: http://www.dave-bond.com/blog/2010/01/JQuery-ajax-progress-HMTL5/
* EDIT * Asegúrese de mirar el segundo ejemplo de código de ese enlace de ejemplo. Creo que el primero está desactualizado con las versiones modernas de jQuery.
$.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;
//Do something with upload progress
console.log(percentComplete);
}
}, false);
//Download progress
xhr.addEventListener("progress", function(evt){
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
//Do something with download progress
console.log(percentComplete);
}
}, false);
return xhr;
},
type: ''POST'',
url: "/",
data: {},
success: function(data){
//Do something success-ish
}
});
Como se sugiere aquí: https://gist.github.com/HenrikJoreteg/2502497 , estoy tratando de agregar la funcionalidad de progreso a mi archivo jQuery.ajax()
. La carga funciona bien, y el evento onprogress se está activando, pero no como lo esperaba, en lugar de disparar repetidamente en algún intervalo de tiempo, se dispara solo una vez, cuando la carga se ha completado. ¿Hay una manera de especificar la frecuencia de las actualizaciones en progreso? O, ¿estoy tratando de hacer algo que no se puede hacer? Aquí está mi código:
$.ajax(
{
async: true,
contentType: file.type,
data: file,
dataType: ''xml'',
processData: false,
success: function(xml)
{
// Do stuff with the returned xml
},
type: ''post'',
url: ''/fileuploader/'' + file.name,
xhrFields:
{
onprogress: function(progress)
{
var percentage = Math.floor((progress.total / progress.totalSize) * 100);
console.log(''progress'', percentage);
if (percentage === 100)
{
console.log(''DONE!'');
}
}
}
});
Esto es un truco de otra respuesta en otra parte de , pero creo que responde a tu pregunta. Lo he solucionado según mis propias necesidades de bombeo de datos "transmitidos" desde el servidor a una división desplazable (que luego puedo forzar para que siempre se desplace hacia la parte inferior, lo que muestra el progreso a lo largo del tiempo y, por lo tanto, no espero que se complete el conjunto completo de registros) .
El código del lado del cliente a continuación agrega el contenido resultante a un div predefinido con id "scrollable_area" (que luego se puede desplazar) ...
<div style="position:absolute; left:5px; right:5px; top:5px; height:35px;">
<label for="auto_scroll">Auto Scroll</label> <input type="checkbox" id="auto_scroll" checked>
</div>
<div id="scrollable_area" style="position:absolute; overflow:auto; left:5px; right:5px; top:45px; bottom:5px;"></div>
<script type="text/javascript">
var last_response_len = false;
var auto_scroll = null;
var scrollable_area = null;
$().ready(function() {
auto_scroll = document.getElementById("auto_scroll");
scrollable_area = document.getElementById("scrollable_area");
$.ajax("your_api_call.php", {
xhrFields: {
onprogress: function(e) {
var this_response, response = e.currentTarget.response;
if(last_response_len === false) {
this_response = response;
last_response_len = response.length;
} else {
this_response = response.substring(last_response_len);
last_response_len = response.length;
}
scrollable_area.innerHTML += this_response;
if(auto_scroll.checked) {
scrollable_area.scrollTop = scrollable_area.clientHeight + scrollable_area.scrollHeight + 500;
}
}
}
})
.done(function(data) {
console.log("Completed response");
})
.fail(function(data) {
console.log("Error: ", data);
});
console.log("your_api_call.php Request Sent!");
});
</script>
El lado del servidor "your_api_call.php" llamada de archivo necesitaría luego vaciar su salida (por fila de datos para ver el progreso en el tiempo) que luego se puede mostrar inmediatamente dentro de la división de "scrollable_area" anterior ...
// Do Db loop
while ($record = $recordset->fetch(PDO::FETCH_ASSOC)) {
set_time_limit(10); // Don''t timeout on large data sets seeing as this is a big task that we are wanting to watch progress!
echo ''Do what you gotta do... '' . $record["register_id"] . ''<br>'';
flush(); // Push to the client / ajax
ob_flush(); // As above
}
Respuesta corta ... SI. Espero que esto ayude :-)
Respuesta corta:
No, no puedes hacer lo que quieres usando xhrFields
.
Respuesta larga:
Hay dos eventos de progreso en un objeto XmlHttpRequest:
El progreso de la respuesta (
XmlHttpRequest.onprogress
)
Esto es cuando el navegador está descargando los datos del servidor.El progreso de la solicitud (
XmlHttpRequest.upload.onprogress
)
Esto es cuando el navegador está enviando los datos al servidor (incluidos los parámetros POST, las cookies y los archivos)
En su código, está utilizando el evento de progreso de respuesta, pero lo que necesita es el evento de progreso de solicitud. Así es como lo haces:
$.ajax({
async: true,
contentType: file.type,
data: file,
dataType: ''xml'',
processData: false,
success: function(xml){
// Do stuff with the returned xml
},
type: ''post'',
url: ''/fileuploader/'' + file.name,
xhr: function(){
// get the native XmlHttpRequest object
var xhr = $.ajaxSettings.xhr() ;
// set the onprogress event handler
xhr.upload.onprogress = function(evt){ console.log(''progress'', evt.loaded/evt.total*100) } ;
// set the onload event handler
xhr.upload.onload = function(){ console.log(''DONE!'') } ;
// return the customized object
return xhr ;
}
});
El parámetro de la opción xhr
debe ser una función que devuelva un objeto XmlHttpRequest nativo para que lo use jQuery.