Как обрабатывать одновременные 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 "та же политика происхождения" или поиск здесь, чтобы узнать больше.