Possible Duplicate:
passing index from for loop to ajax callback function (javascript)
I've been a little confused with making xmlhttprequests, to different servers, in order to fetch some content.. Here is what I've written, but it seems that I'm mistaken at some point..
var URL = new Array();
URL[0] = "http://www.example1.com";
URL[1] = "http://www.example2.com";
URL[2] = "http://www.example3.com";
var nRequest = new Array();
for (var i=0; i<3; i++) {
nRequest[i] = new XMLHttpRequest();
nRequest[i].open("GET", URL[i], true);
nRequest[i].onreadystatechange = function (oEvent) {
if (nRequest[i].readyState === 4) {
if (nRequest[i].status === 200) {
console.log(nRequest[i].responseText);
alert(nRequest[i].responseText);
} else {
console.log("Error", nRequest[i].statusText);
}
}
};
nRequest[i].send(null);
}
with this code on I.E.10 I get access denied on console..
If I remove array and use simple request, it operates as expected..
wRequest = new XMLHttpRequest();
wRequest.open("GET", "http://www.example1.com", true);
wRequest.onreadystatechange = function (oEvent) {
if (wRequest.readyState === 4) {
if (wRequest.status === 200) {
console.log(wRequest.responseText);
alert(wRequest.responseText);
} else {
console.log("Error", wRequest.statusText);
}
}
};
wRequest.send(null);
But how am I supposed to trigger multiple 2-3 requests, and still not have problem with data handling..??
The problem (ignoring the cross-domain issue that slebetman covered) is that when your ready state change callback is fired it is using the i
variable from the containing scope which will be 3
after the loop completes. One way to fix that is as follows:
for (var i=0; i<3; i++){
(function(i) {
nRequest[i] = new XMLHttpRequest();
nRequest[i].open("GET", URL[i], true);
nRequest[i].onreadystatechange = function (oEvent) {
if (nRequest[i].readyState === 4) {
if (nRequest[i].status === 200) {
console.log(nRequest[i].responseText);
alert(nRequest[i].responseText);
} else {
console.log("Error", nRequest[i].statusText);
}
}
};
nRequest[i].send(null);
})(i);
}
This introduces an immediately invoked function expression for each loop iteration such that the code inside the function has its own i
- the magic of JS closures means that when the onreadystatechange
function is called it will access the parameter i
of the anonymous function (even though that function has completed), not the i
of the outer scope, so the right nRequest
element will be processed each time.
Also you had a typo on the .open()
line where you said wURL[i]
but should've had URL[i]
.
Depending on what you plan to do with the response text I'm not sure that you need an array of requests at all: you could encapsulate the Ajax code into a function that takes a URL and a callback function as parameters, and then call that function in the loop...