2011-04-09 83 views
0

我正在开发一个JavaScript代码以使用ANT Galio浏览器在嵌入式设备上运行。XmlHttpRequest返回状态4太快

理想情况下,我想让代码向另一台服务器发出获取请求。在获取请求之后,该页面将不允许用户提交另一个获取请求,直到从前一个获取请求收到响应为止。

出于某种原因,有时候我几乎立刻就会收到4个readyState。就好像它正在评估以前的XmlHttpRequest对象而不是新的对象。我究竟做错了什么?

<script type="text/javascript"> 

var fail= function (env, resp, stat) { 

     alert(resp); 
}; 
var succ= function (env, resp) { 
}; 

var canScan = true; 

/* start scan */ 
function scan (name) { 
     if (canScan) { 
       //deactivate button 
       deactivateScanButtons(); 
       //let server know 
       ajax = new XMLHttpRequest(); 
       var scanUrl = 'http://19X.1XX.X.XX:8080/scan/' + name 
       ajax.open('GET', scanUrl, true); 
       ajax.onreadystatechange = function() { 
         if (ajax.readyState==4) { 
           //allow button to work again 
           activateScanButtons(); 
           alert("ready state 4"); 


         }; 
       }; 

       ajax.send(); 
//initiate scan 
       xrxScanInitiateScan(
         'http://127.0.0.1', 
         "ftp.xst", 
         false, 
         succ, 
         fail); 
     } 

} 

function deactivateScanButtons() { 
//  canScan = false; 

     var indicator = document.getElementById('buttons'); 
     indicator.style.visibility = "hidden"; 
} 
function activateScanButtons() { 
//  canScan = true; 

     var indicator = document.getElementById('buttons'); 
     indicator.style.visibility = "visible"; 

} 
</script> 

回答

1

3建议:

  1. 为了避免客户端的任何缓存中,添加一个随机生成的号码,或当前时间戳请求查询字符串。
  2. 正如Yoni所说,用var关键字启动您的XMLHttpRequest对象。
  3. 对于每个请求,将当前时间戳保存在全局变量中。在onreadystatechange中,仅当全局时间戳与该给定请求的相应时间戳匹配时才调用activateScanButtons。这样,只有最新的请求才能拨打activateScanButtons
+0

这工作得很好。谢谢。 – SLY 2011-04-13 11:13:37

1

您在scan函数定义的Ajax对象没有收到var关键字。这意味着它是一个全局对象,不是本地的。之后,你有一个关闭 - 你在onreadystate回调函数中引用该变量。

我发现很难跟踪到底发生了什么,但我同意你的看法,就像你在问题中所说的那样,回调并没有按照你期望的方式使用ajax对象。你说它有时会发生 - 当你几乎同时发出两个请求(双击一个按钮或以非常快的速度触发两个请求时)会发生吗?

我建议您在定义ajax对象之前使用var关键字。更好的是,在回调函数中尝试使用this,而不是按名称引用ajax对象。如果它有效,你可以避免一次关闭。