I tried three different ways to intercept the construction of an Ajax object:
- My first attempt used
xhrFields , but this only allows one listener, only attaches to the load (does not load), and requires what seems like unnecessary copy and paste. - My second attempt attached the
progress function to the returned promise, but I had to maintain my own array of handlers. I could not find a good object for attaching handlers, because in one place I could access XHR and the other I would have access to jQuery XHR, but I never had access to the deferred object (only its promise). - My third attempt gave me direct access to XHR to bind handlers, but again required a lot of code to copy and paste.
- I wrapped my third attempt and replaced jQuery
ajax with my own. The only potential downside is that you can no longer use your own xhr() parameter. You can enable this by checking to see if there is an options.xhr function.
I really call my promise.progress function promise.progress , so I can easily find it later. You might want to call this something else to separate download and download listeners. Hope this helps someone, even if the original poster has already received what it needs.
(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) { // Download progress xmlHttpReq.addEventListener('progress', function download_progress(evt) { // window.console.debug( "download_progress", evt ); handler.apply(this, [evt]); }, false); // Upload progress 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);
MarkMYoung Feb 03 '14 at 17:58 2014-02-03 17:58
source share