Answers:
对于上传的字节,这非常容易。只是监视xhr.upload.onprogress
事件。浏览器知道它必须上传的文件的大小以及上传的数据的大小,因此它可以提供进度信息。
对于下载的字节(通过获取信息时xhr.responseText
),要困难一些,因为浏览器不知道服务器请求中将发送多少字节。在这种情况下,浏览器唯一知道的就是它接收的字节大小。
有一个解决方案,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();
}
Firefox支持XHR下载进度事件。
对于上载的总数,似乎没有一种处理方法,但是有些与您要下载的内容相似。一旦readyState为3,您就可以定期查询responseText以下载所有内容,直到一个String为止(这在IE中不起作用),直到所有内容都可用时为止,它都将过渡到readyState 4。在任何给定时间下载的字节数将等于responseText中存储的字符串中的总字节数。
对于上载问题的全有或全无方法,由于必须传递一个用于上载的字符串(并且可以确定该字符串的总字节数),为readyState 0和1发送的总字节数将为0,而为readyState发送的总数为0 2是您传入的字符串中的总字节。在readyState 3和4中发送和接收的总字节将是原始字符串中的字节总和加上responseText中的总字节。
<!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>
如果您有权访问apache安装并信任第三方代码,则可以使用apache上载进度模块(如果使用apache;还有一个nginx上载进度模块)。
否则,您将必须编写一个脚本,可以带外使用该脚本来请求文件的状态(例如,检查tmp文件的文件大小)。
我相信在firefox 3中正在进行一些工作,我相信会为浏览器添加上载进度支持,但是这并不会渗透到所有浏览器中,并且会在一段时间内被广泛采用(更可惜的是)。
用纯JavaScript做到这一点的唯一方法是实现某种轮询机制。您将需要以固定的间隔(例如每5秒发送一次)发送ajax请求,以获取服务器接收到的字节数。
一种更有效的方法是使用闪存。弹性组件FileReference定期调度一个'progress'事件,该事件持有已上传的字节数。如果您需要坚持使用javascript,则可以在actionscript和javascript之间建立桥梁。好消息是这项工作已经为您完成:)
该库允许在Flash Progress事件上注册一个javascript处理程序。
该解决方案具有不需要服务器端额外资源的缺点。