如何从XMLHttpRequest获得进展

是否有可能获得XMLHttpRequest(字节上传,字节下载)的进展?

这对于在用户上传大文件时显示进度条非常有用。 标准的API似乎不支持它,但也许有一些非标准的扩展在那里的任何浏览器? 毕竟,这似乎是一个非常明显的特征,因为客户端知道有多less字节被上传/下载。

注意:我知道“轮询服务器的进展”的select(这是我现在正在做的)。 这个问题(除了复杂的服务器端代码)通常是在上传一个大文件的时候,用户的连接是完全混乱的,因为大多数ISP提供的上行不好。 所以提出额外的请求并不像我希望的那样快速响应。 我希望有一个方法(也许是非标准的)来获取浏览器所有的这些信息。

对于上传的字节是很容易的。 只要监视xhr.upload.onprogress事件。 浏览器知道上传文件的大小和上传数据的大小,因此可以提供进度信息。

对于下载的字节(当用xhr.responseText获取信息的xhr.responseText ),这有点困难,因为浏览器不知道在服务器请求中将发送多less字节。 浏览器在这种情况下唯一知道的就是它正在接收的字节的大小。

有一个解决scheme,在服务器脚本上设置一个Content-Length头是足够的,以便获得浏览器将要接收的字节的总大小。

有关更多信息,请访问https://developer.mozilla.org/en/Using_XMLHttpRequest

示例:我的服务器脚本读取一个zip文件(需要5秒):

 $filesize=filesize('test.zip'); header("Content-Length: " . $filesize); // set header length // if the headers is not set then the evt.loaded will be 0 readfile('test.zip'); exit 0; 

现在我可以监视服务器脚本的下载过程,因为我知道它是总长度:

 function updateProgress(evt) { if (evt.lengthComputable) { // evt.loaded the bytes the browser received // evt.total the total bytes set by the header // jQuery UI progress bar to show the progress on screen var percentComplete = (evt.loaded / evt.total) * 100; $('#progressbar').progressbar( "option", "value", percentComplete ); } } function sendreq(evt) { var req = new XMLHttpRequest(); $('#progressbar').progressbar(); req.onprogress = updateProgress; req.open('GET', 'test.php', true); req.onreadystatechange = function (aEvt) { if (req.readyState == 4) { //run any callback here } }; req.send(); } 

AJAX模式的Progress Indicator有一个很好的讨论:

http://ajaxpatterns.org/Progress_Indicator

最有希望的方法之一似乎是打开第二个通信渠道回到服务器,问它已经完成了多less转移。

Firefox支持XHR下载进度事件 。

Firefox 3.5将支持上传进度事件

对于上传的总量似乎没有办法处理,但有一些类似于你想要下载的东西。 一旦readyState为3,您可以定期查询responseText以获取所有下载的内容,直到string(这在IE中不起作用),直到所有内容都可用,在这一点上它将转换到readyState 4.总数在任何给定时间下载的字节数将等于存储在responseText中string的总字节数。

对于上传问题的全部或全部方法,因为你必须传递一个string上传(并且可以确定总字节数),所以为readyState 0和1发送的总字节数将是0,而readyState 2将是您传递的string中的总字节数。在readyState 3和4中发送和接收的总字节数将是原始string中的字节数加上responseText中的总字节数的总和。

如果你有权访问你的apache安装并且信任第三方代码,你可以使用apache上传进度模块 (如果你使用apache;还有一个nginx上传进度模块 )。

否则,你必须编写一个脚本,你可以点击带外请求文件的状态(例如检查tmp文件的文件大小)。

在firefox 3中有一些工作正在进行中,我相信为浏览器添加上传进度支持,但是这并不会进入所有的浏览器,并被广泛采用一段时间(更可惜)。

 <!DOCTYPE html> <html> <body> <p id="demo">result</p> <button type="button" onclick="get_post_ajax();">Change Content</button> <script type="text/javascript"> function update_progress(e) { if (e.lengthComputable) { var percentage = Math.round((e.loaded/e.total)*100); console.log("percent " + percentage + '%' ); } else { console.log("Unable to compute progress information since the total size is unknown"); } } function transfer_complete(e){console.log("The transfer is complete.");} function transfer_failed(e){console.log("An error occurred while transferring the file.");} function transfer_canceled(e){console.log("The transfer has been canceled by the user.");} function get_post_ajax() { var xhttp; if (window.XMLHttpRequest){xhttp = new XMLHttpRequest();}//code for modern browsers} else{xhttp = new ActiveXObject("Microsoft.XMLHTTP");}// code for IE6, IE5 xhttp.onprogress = update_progress; xhttp.addEventListener("load", transfer_complete, false); xhttp.addEventListener("error", transfer_failed, false); xhttp.addEventListener("abort", transfer_canceled, false); xhttp.onreadystatechange = function() { if (xhttp.readyState == 4 && xhttp.status == 200) { document.getElementById("demo").innerHTML = xhttp.responseText; } }; xhttp.open("GET", "http://it-tu.com/ajax_test.php", true); xhttp.send(); } </script> </body> </html> 

唯一的方法是使用纯javascript来实现某种轮询机制。 您将需要以固定的时间间隔(例如,每5秒)发送一次Ajax请求,以获取服务器接收到的字节数。

更有效的方法是使用闪光灯。 flex组件FileReference定期发送一个“progress”事件来保存已经上传的字节数。 如果你需要坚持使用javascript,动作和JavaScript之间的桥梁可用。 好消息是,这项工作已经为你做了:)

SWFUpload的

这个库允许在Flash进度事件上注册一个JavaScript处理程序。

这个解决scheme具有不需要服务器端上的其他资源的好处。