5

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..??

David
  • 3,055
  • 1
  • 31
  • 48
nikolas
  • 663
  • 2
  • 13
  • 36
  • 4
    You cannot use AJAX to read data from a different domain. – SLaks Nov 18 '12 at 23:42
  • I see a typo `wURL` --> `URL`, a closure issue `i` inside anonymous function and same origin policy issue. – Musa Nov 18 '12 at 23:48
  • why do i get data though from just a single domain? – nikolas Nov 18 '12 at 23:49
  • 1
    [CORS](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing) maybe? – Musa Nov 18 '12 at 23:53
  • I can't post a full answer (because the question is marked as a duplicate) but you can store a value in the request object before sending the request `request.myParameter = myValue` --- and then access this value inside the listener function using the event parameter that you get there: `iEvent.target.myParameter`. Hope this helps someone! – sunyata Jun 20 '19 at 17:00

2 Answers2

13

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...

nnnnnn
  • 138,378
  • 23
  • 180
  • 229
  • 1
    that did the trick..!!! recently i had issue on another case with js' scope, and it seems that i faced it again...thank you very much..!!! – nikolas Nov 18 '12 at 23:57
  • You're welcome. What I've shown is the minimal change to your existing code to make it work, but there are (in my opinion) nicer ways to structure the whole thing - probably outside the scope of this question though. – nnnnnn Nov 18 '12 at 23:59
  • the typo, was just trying code to appear friendlier, than my original name handling of the variables...as for my respone text, i m just trying to make a mashup application, that collects data from 2-3 different sites, and gathers some specific information from each..that's why i thought it would be better to use an array.. – nikolas Nov 19 '12 at 00:00
  • could you elaborate, on the different approach that you suggest that i could handle the request? – nikolas Nov 19 '12 at 00:03
1

making xmlhttprequests, to different servers

You cannot do that. XMLHttpRequest is only allowed to connect to the same domain that the page belongs to. This is called the "same origin policy".

Google "same origin policy" or search for it here on SO to learn more.

slebetman
  • 93,070
  • 18
  • 116
  • 145
  • thank you for your response, however, for some reason, i do get a response, when i trigger the single request.. – nikolas Nov 18 '12 at 23:52