Javascript 获取jQueryAjax请求进度的最干净的方法是什么?
在普通javascript中非常简单:只需将回调附加到Javascript 获取jQueryAjax请求进度的最干净的方法是什么?,javascript,ajax,jquery,xmlhttprequest,Javascript,Ajax,Jquery,Xmlhttprequest,在普通javascript中非常简单:只需将回调附加到{XMLHTTPRequest}.onprogress var xhr = new XMLHttpRequest(); xhr.onprogress = function(e){ if (e.lengthComputable) var percent = (e.loaded / e.total) * 100; }; xhr.open('GET', 'http://www...', true); xhr.onread
{XMLHTTPRequest}.onprogress
var xhr = new XMLHttpRequest();
xhr.onprogress = function(e){
if (e.lengthComputable)
var percent = (e.loaded / e.total) * 100;
};
xhr.open('GET', 'http://www...', true);
xhr.onreadystatechange = function() {
...
};
xhr.send(null);
但我正在做一个ajax站点,它使用JQuery下载html数据(
$.get()
或$.ajax()
),我想知道哪种方法是获取请求进度的最佳方法,以便用一个小进度条显示请求,但奇怪的是,我在JQuery文档中找不到任何有用的东西…JQuery有一个函数,它允许您为所有ajax调用注册全局ajax处理程序,例如在发送之前注册和完成,并允许您访问xhr
对象来完成您正在寻找的进程$.ajax
(仅限HTML5):
我尝试了三种截取Ajax对象构造的不同方法:
我的第一次尝试使用了xhrFields
,但这只允许一个侦听器,只附加到下载(而不是上载)进度,并且需要看起来不必要的复制和粘贴李>
我的第二次尝试将progress
函数附加到返回的承诺中,但我必须维护自己的处理程序数组。我找不到一个好的对象来附加处理程序,因为一个地方我可以访问XHR,另一个地方我可以访问jQuery XHR,但我从来没有访问过延迟对象(只有它的承诺)李>
我的第三次尝试使我能够直接访问XHR以附加处理程序,但同样需要大量复制和粘贴代码李>
我结束了第三次尝试,用我自己的jQuery的ajax
。唯一的潜在缺点是您不能再使用自己的xhr()
设置。您可以通过检查options.xhr
是否是一个函数来实现这一点
我实际上调用了我的promise.progress
函数xhrProgress
,这样我以后就可以很容易地找到它了。您可能希望将其命名为其他名称,以分离您的上载和下载侦听器。我希望这能帮助一些人,即使原来的海报已经得到了他所需要的
(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 );
我正在寻找一个类似的解决方案,并发现这一个使用充分
var es;
function startTask() {
es = new EventSource('yourphpfile.php');
//a message is received
es.addEventListener('message', function(e) {
var result = JSON.parse( e.data );
console.log(result.message);
if(e.lastEventId == 'CLOSE') {
console.log('closed');
es.close();
var pBar = document.getElementById('progressor');
pBar.value = pBar.max; //max out the progress bar
}
else {
console.log(response); //your progress bar action
}
});
es.addEventListener('error', function(e) {
console.log('error');
es.close();
});
}
和您的服务器输出
header('Content-Type: text/event-stream');
// recommended to prevent caching of event data.
header('Cache-Control: no-cache');
function send_message($id, $message, $progress) {
$d = array('message' => $message , 'progress' => $progress); //prepare json
echo "id: $id" . PHP_EOL;
echo "data: " . json_encode($d) . PHP_EOL;
echo PHP_EOL;
ob_flush();
flush();
}
//LONG RUNNING TASK
for($i = 1; $i <= 10; $i++) {
send_message($i, 'on iteration ' . $i . ' of 10' , $i*10);
sleep(1);
}
send_message('CLOSE', 'Process complete');
标题(“内容类型:文本/事件流”);
//建议防止缓存事件数据。
标头(“缓存控制:无缓存”);
函数send_message($id,$message,$progress){
$d=array('message'=>$message,'progress'=>$progress);//准备json
echo“id:$id”;
echo“data:”.json_encode($d).PHP_EOL;
echo PHP_EOL;
ob_flush();
冲洗();
}
//长时间运行任务
对于($i=1;$ijQuery已经实现了承诺,因此最好使用此技术,不要将事件逻辑移动到options
参数。我制作了一个jQuery插件,添加了进度承诺,现在它与其他承诺一样易于使用:
在上查看,按照以下步骤显示Ajax请求的进度:
使用Html和CSS创建微调器或使用引导微调器
当最终用户请求无限循环或阈值限制时间的AJAX数据时,显示微调器
因此,在AJAX请求的成功/错误结果之后,移除当前显示的微调器并显示结果
为了方便起见,我建议您使用JS类动态显示和隐藏微调器
我希望这会有帮助!这一个看起来很有希望用于html5Ooh谢谢大家!所以需要重写xhr。.奇怪的是,我用Chrome开发工具检查了所谓的jqXHR
对象(由$.ajax()
返回的xhr对象的包装器),并在其中找到了progress
属性(还有中止
,完成
,成功
,等等),但在JQuery文档中,这一点是缺失的:我使用这个,它与其他答案完全相同,但我更喜欢更通用的东西。谢谢链接。你能在回答中包括一个例子吗?$.ajaxSetup({xhr:function(){console.log('setup xhr…);});还有一个例子可以回答这个问题吗?恐怕我无法给出一个让我做了大量的修改和阅读的答案,特别是当链接页面上没有任何关于进度的内容时。老实说,我对此表示怀疑,特别是考虑到该页面上的警告,即“注意:全局回调函数应该设置为各自的全局Ajax事件处理程序方法-.ajaxStart()
,.ajaxStop()
,.ajaxComplete()
,.ajaxError()
,.ajaxSuccess()
,.ajaxSend()
,而不是在$.ajaxSetup()的选项对象中
:为将来的Ajax请求设置默认值。不建议使用它。所以我只是尝试实现您的解决方案,但这段代码有点过于专业,我无法理解-如何使用它?我在我的文档之前复制粘贴了您的整段代码。准备并尝试执行$.Ajax({…})。进度(函数(evl){console.log(evl);});
但是什么也没发生。你能帮我吗?:)您使用的是哪个版本的jQuery?@FloSchild,请不要仅仅为了您自己的格式设置而编辑我的代码。我喜欢您使用IFI工厂的方式。我不知道这种技术!这是目前这里建议的最佳解决方案。这是一种可行且优雅的解决方案,但您可能知道它可能会破坏您现有的代码,因为它中断对已弃用的.success和.error的所有调用。它还会剥离您在jqXHR对象上设置的所有非标准属性。它不会为uploadProgress回调提供“this”上下文(可能与progress相同,但未测试)正如jqXHR的所有标准承诺一样。因此,您需要在闭包中传递上下文。我得到错误:TypeError:$.ajax(…).progress(…)。progressUpload不是一个函数
。。。。
header('Content-Type: text/event-stream');
// recommended to prevent caching of event data.
header('Cache-Control: no-cache');
function send_message($id, $message, $progress) {
$d = array('message' => $message , 'progress' => $progress); //prepare json
echo "id: $id" . PHP_EOL;
echo "data: " . json_encode($d) . PHP_EOL;
echo PHP_EOL;
ob_flush();
flush();
}
//LONG RUNNING TASK
for($i = 1; $i <= 10; $i++) {
send_message($i, 'on iteration ' . $i . ' of 10' , $i*10);
sleep(1);
}
send_message('CLOSE', 'Process complete');
$.ajax(url)
.progress(function(){
/* do some actions */
})
.progressUpload(function(){
/* do something on uploading */
});