Как обрабатывать одновременные javascript xmlhttprequests?

Возможный дубликат:
передача индекса из цикла for в функцию обратного вызова ajax (javascript)

Я немного запутался в создании xmlhttprequests для разных серверов, чтобы получить какой-то контент... Вот что я написал, но в какой-то момент я ошибаюсь...

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);
}

с этим кодом на IE10 я получаю отказано в доступе на консоли..

Если я удаляю массив и использую простой запрос, он работает как положено..

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);

Но как я должен вызвать несколько 2-3 запросов, и все еще не имеют проблемы с обработкой данных..??

2 ответа

Решение

Проблема (игнорируя междоменную проблему, которую рассмотрел slebetman) состоит в том, что, когда ваш обратный вызов изменения состояния готов, он использует i переменная из содержащей области, которая будет 3 после завершения цикла. Один из способов исправить это следующим образом:

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);
}

Это вводит сразу вызываемое выражение функции для каждой итерации цикла, так что код внутри функции имеет свой собственный i - магия закрытия JS означает, что когда onreadystatechange вызывается функция доступа к параметру i анонимной функции (даже если эта функция завершена), а не i внешней сферы, так что право nRequest элемент будет обрабатываться каждый раз.

Также у вас была опечатка на .open() линия, где вы сказали wURL[i] но должен был URL[i],

В зависимости от того, что вы планируете делать с текстом ответа, я не уверен, что вам вообще нужен массив запросов: вы можете инкапсулировать код Ajax в функцию, которая принимает URL и функцию обратного вызова в качестве параметров, а затем вызывать ее функция в цикле...

создание xmlhttprequests для разных серверов

Тебе этого не сделать. XMLHttpRequest разрешено подключаться только к тому же домену, к которому принадлежит страница. Это называется "политикой того же происхождения".

Google "та же политика происхождения" или поиск здесь, чтобы узнать больше.

Другие вопросы по тегам