我现在正在努力争取这一天,并且非常感谢圈内和帮助:-)
摘要
异步ajax用解析器和fqdn变量调用cgi,以便再次返回dns分辨率。 (返回dig @resolver $ fqdn的输出)
问题
在firebug中,我可以看到get请求是异步触发的,并且对浏览器的响应是预期的。但是我无法将响应放在doc中的正确div中,因为onreadystatechange无法识别对象。
旁注
除了我在迭代对象数组这一事实之外,即使迭代之间的延迟被放置,它们似乎也会瞬间被触发。
以下是我的评论代码
由于解析器是一个数组,我创建了一个xmlhttprequest对象数组。
function resolve() {
var numofres = 6;
var arr = new Array;
arr[0] = "192.168.1.11";
arr[1] = "8.8.8.8";
arr[2] = "8.8.4.4";
arr[3] = "159.134.0.1";
arr[4] = "159.134.0.2";
var len = arr.length;
var ax = new Array(); //creating ax as an array
for (var i=0; i<=len; i++) { //iterating through the length of resolvers array
ax[i] = new XMLHttpRequest(); //assigning to each item in array new object
//alert(ax[i]); // shows that object exists
ax[i].onreadystatechange = function(){
/*===
problem is above - firebug will show:
**Uncaught TypeError: Cannot read property 'readyState' of undefined**
**ax.(anonymous function).onreadystatechangehello.cgi:30**
oddly it will still populate divs inner html with 'loading +1 '
albeit regardless of readystate code (can be 4 or anything else )
It perplexes me why i is thought as a function?
=====*/
// alert(i); //if this is enabled I will see readyState==4 populated correctly
if (ax[i].readyState != 4) {
document.getElementById('return_table_'+i).innerHTML="loading "+i;
}
if(ax[i].readyState == 4){
// get data from the server response
var response_ready=ax[i].responseText;
document.getElementById('return_table_'+i).innerHTML = response_ready;
}
}
ax[i].open("GET","av.pl?resolver=" + arr[i] +"&fqdn=google.com",true); //works
ax[i].send(null); //works
}
}
答案 0 :(得分:2)
你的问题非常普遍。在JavaScript中,变量的作用域是函数级别,而不是块语句级别。因此,当您使用变量“i”迭代该循环时,您在循环中创建的每个函数共享相同的“i”。因此,当函数实际上被称为时,“i”的值将是它在循环结束时的值 - 这是超出数组末尾的点!
要避免此问题,您需要在另一个功能中创建这些功能。一个干净的方法是使用单独的本地函数:
function makeReadyStateHandler(i) {
return function() {
if (ax[i].readyState != 4) {
document.getElementById('return_table_'+i).innerHTML="loading "+i;
}
if(ax[i].readyState == 4){
// get data from the server response
var response_ready=ax[i].responseText;
document.getElementById('return_table_'+i).innerHTML = response_ready;
}
};
}
然后从循环中调用该函数:
ax[i].onreadystatechange = makeReadyStateHandler(i);
通过使用这样的单独函数,可以确保每个处理函数都有自己的“i”副本,该副本在循环中的正确位置被冻结。该函数将返回一个新创建的函数作为其结果,您将其用作事件处理程序。