用AJAX实现进度条(2.客户端)

上次提到的用AJAX实现进度条时,服务器端必须提供一个用于查询状态的接口。接下来,在浏览器客户端要做的事情就是:

  1. 发起服务请求
  2. 调用查询状态的接口进行状态轮询
  3. 用进度条显示状态

1.发起服务请求

接着上次的例子,发起服务请求也就是向服务器发起导出Excel的请求,请求export.php并传入参数export_id,export.php执行完毕之后,会返回导出的Excel文件的地址。下面是用AJAX调用的代码:
[javascript]
finished = false;
var xmlHttp = GetXmlHttpObject();
var stateChanged = function(){
if(xmlHttp.readyState==4){
finished = true;
document.location.href=xmlHttp.responseText;
}
}
xmlHttp.onreadystatechange=stateChanged;
xmlHttp.open("GET","export.php?export_id=xxx",true);
xmlHttp.send(null);
[/javascript]

2.状态轮询

上篇的例子中,status.php每次返回的是一个JSON对象,包括了三个key:current_step、total_step和msg。下面的代码中用AJAX方式轮询状态,并将状态用文本显示出来。
[javascript]
var xmlHttp2 = GetXmlHttpObject();
var stateChanged2 = function (){
if (xmlHttp2.readyState==4){
if(xmlHttp2.status==200){
var obj = eval('(' + xmlHttp2.responseText + ')');
document.getElementById("t1").innerHTML=
"["+obj.current_step+"/"+obj.total_step+"]"+obj.msg;
if(!finished){
setTimeout(onTimerEvent, 1000);
}
}
}
}
var onTimerEvent = function (){
xmlHttp2.open("GET","status.php?export_id=xxx",true);
xmlHttp2.send(null);
}
xmlHttp2.onreadystatechange=stateChanged2;
setTimeout(onTimerEvent,1000);
[/javascript]
setTimeout函数的作用就是指定在一段时间后调用某个函数,它接受两个参数,第一个参数为一个函数对象,第二个参数指定等待的时间。

进度条显示

我使用了extJS进行进度条显示,方法非常简单,在页面上创建一个ProgressBar对象,然后每次查询完状态之后,调用Ext.ProgressBar.updateProgress(percent,msg)方法更新进度条的显示状态。percent是0至1之间的数字,表示当前的进度,msg则是显示在状态条上的文字。结合上面的两个步骤,一个完整的客户端页面如下:示例页面
[javascript]
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>AJAX progress bar</title>

<link rel="stylesheet" type="text/css" href="../ext-3.0.0/resources/css/ext-all.css" />
<script type="text/javascript" src="../ext-3.0.0/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="../ext-3.0.0/ext-all.js"></script>

<script type="text/javascript">
function do_export(){
finished = false;
var xmlHttp = GetXmlHttpObject();
var stateChanged = function(){
if(xmlHttp.readyState==4){
finished = true;
document.location.href=xmlHttp.responseText;
}
}
xmlHttp.onreadystatechange=stateChanged;
xmlHttp.open("GET","export.php?export_id=xxx",true);
xmlHttp.send(null);
}
function check_status(){
var xmlHttp2 = GetXmlHttpObject();
var stateChanged2 = function (){
if (xmlHttp2.readyState==4){
if(xmlHttp2.status==200){
var obj = eval('(' + xmlHttp2.responseText + ')');
pbar.updateProgress(
obj.current_step/obj.total_step,
"["+obj.current_step+"/"+obj.total_step+"]"+obj.msg);
if(!finished){
setTimeout(onTimerEvent, 1000);
}
}
}
}
var onTimerEvent = function (){
xmlHttp2.open("GET","status.php?export_id=xxx",true);
xmlHttp2.send(null);
}
xmlHttp2.onreadystatechange=stateChanged2;
setTimeout(onTimerEvent,1000);
}
function run() {
do_export();
check_status();
}
function GetXmlHttpObject(){
var xmlHttp=null;
try {
xmlHttp=new XMLHttpRequest();
}catch (e){
try{
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}catch (e){
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
}
return xmlHttp;
}
Ext.onReady(function(){
pbar = new Ext.ProgressBar({
text:"Ready",
id:"pbar",
style:"text-align:left",
renderTo:'p'
});
var btn = Ext.get("btn");
btn.on('click',run);
});
</script>
</head>
<body>
<p>
<button id="btn">Run</button><br />
<div id="p" style="width:50%;"></div>
</p>
</body>
</html>
[/javascript]


Last modified on 2009-11-08