J'ai essayé environ trois façons différentes d'intercepter la construction de l'objet Ajax :
- Ma première tentative a utilisé
xhrFields
mais cela ne permet qu'une seule écoute, ne s'attache qu'à la progression du téléchargement (et non de l'envoi), et nécessite ce qui semble être un copier-coller inutile.
- Ma deuxième tentative a attaché un
progress
à la promesse retournée, mais je devais maintenir mon propre tableau de gestionnaires. Je n'ai pas pu trouver un bon objet pour attacher les handlers parce qu'à un endroit j'avais accès au XHR et à un autre j'avais accès au XHR de jQuery, mais je n'avais jamais accès à l'objet différé (seulement sa promesse).
- Ma troisième tentative m'a permis d'accéder directement au XHR pour attacher des gestionnaires, mais elle nécessitait à nouveau trop de copier-coller de code.
- J'ai terminé ma troisième tentative et j'ai remplacé l'élément de jQuery
ajax
avec les miens. Le seul inconvénient potentiel est que vous ne pouvez plus utiliser votre propre xhr()
réglage. Vous pouvez tenir compte de cette possibilité en vérifiant si options.xhr
est une fonction.
En fait, j'appelle mon promise.progress
fonction xhrProgress
pour que je puisse le retrouver facilement plus tard. Vous pourriez lui donner un autre nom pour séparer vos auditeurs de téléchargement et de chargement. J'espère que cela aidera quelqu'un, même si le posteur original a déjà obtenu ce dont il avait besoin.
(function extend_jQuery_ajax_with_progress( window, jQuery, undefined )
{
var $originalAjax = jQuery.ajax;
jQuery.ajax = function( url, options )
{
if( typeof( url ) === 'object' )
{options = url;url = undefined;}
options = options || {};
// Instantiate our own.
var xmlHttpReq = $.ajaxSettings.xhr();
// Make it use our own.
options.xhr = function()
{return( xmlHttpReq );};
var $newDeferred = $.Deferred();
var $oldPromise = $originalAjax( url, options )
.done( function done_wrapper( response, text_status, jqXHR )
{return( $newDeferred.resolveWith( this, arguments ));})
.fail( function fail_wrapper( jqXHR, text_status, error )
{return( $newDeferred.rejectWith( this, arguments ));})
.progress( function progress_wrapper()
{
window.console.warn( "Whoa, jQuery started actually using deferred progress to report Ajax progress!" );
return( $newDeferred.notifyWith( this, arguments ));
});
var $newPromise = $newDeferred.promise();
// Extend our own.
$newPromise.progress = function( handler )
{
xmlHttpReq.addEventListener( 'progress', function download_progress( evt )
{
//window.console.debug( "download_progress", evt );
handler.apply( this, [evt]);
}, false );
xmlHttpReq.upload.addEventListener( 'progress', function upload_progress( evt )
{
//window.console.debug( "upload_progress", evt );
handler.apply( this, [evt]);
}, false );
return( this );
};
return( $newPromise );
};
})( window, jQuery );
4 votes
Celui-ci semble prometteur dave-bond.com/blog/2010/01/JQuery-ajax-progress-HMTL5 pour html5
1 votes
Ooh merci les gars ! il faut donc remplacer xhr la chose étrange est que j'ai inspecté avec Chrome Dev Tools la soi-disant
jqXHR
(l'enveloppe de l'objet xhr retourné par$.ajax()
) et a trouvé unprogress
dans celui-ci (avec l'attributabort
,complete
,success
etc.), mais dans la documentation de JQuery, ce point est absent : api.jquery.com/jQuery.ajax/#jqXHR3 votes
github.com/englercj/jquery-ajax-progress J'utilise ceci et c'est à peu près la même chose que les autres réponses mais je préfère avoir des choses plus génériques.