Tôi đã thử về ba cách khác nhau để chặn việc xây dựng đối tượng Ajax:
- Lần thử đầu tiên của tôi được sử dụng
xhrFields
, nhưng điều đó chỉ cho phép một người nghe, chỉ đính kèm với tiến trình tải xuống (không tải lên) và yêu cầu những gì có vẻ giống như sao chép và dán không cần thiết.
- Lần thử thứ hai của tôi đã gắn một
progress
hàm vào lời hứa trả về, nhưng tôi phải duy trì mảng trình xử lý của riêng mình. Tôi không thể tìm thấy một đối tượng tốt để đính kèm các trình xử lý vì một nơi tôi muốn truy cập vào XHR và một nơi khác tôi có quyền truy cập vào jQuery XHR, nhưng tôi chưa bao giờ có quyền truy cập vào đối tượng hoãn lại (chỉ là lời hứa của nó).
- Lần thử thứ ba của tôi đã cho tôi quyền truy cập trực tiếp vào XHR để đính kèm các trình xử lý, nhưng lại yêu cầu nhiều mã sao chép và dán.
- Tôi đã kết thúc lần thử thứ ba của mình và thay thế jQuery
ajax
bằng của riêng tôi. Thiếu sót tiềm ẩn duy nhất là bạn không thể sử dụng xhr()
cài đặt của riêng mình nữa. Bạn có thể cho phép điều đó bằng cách kiểm tra xem có phải options.xhr
là một chức năng hay không.
Tôi thực sự gọi promise.progress
hàm của mình xhrProgress
để tôi có thể dễ dàng tìm thấy nó sau này. Bạn có thể muốn đặt tên khác cho nó để tách phần nghe tải lên và tải xuống. Tôi hy vọng điều này sẽ giúp ích cho ai đó ngay cả khi người đăng ban đầu đã có những gì anh ta cần.
(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 );