объект XMLHttpRequest.события onload не вызывается
я играю с этим XmlHttpRequest
вещь. В некоторых учебниках и книгах, это onload
функция, вызываемая при выполнении запроса. В моем маленьком эксперименте, эта функция никогда не вызывается. Вот мой код:
window.onload = function() {
var url = "http://www.google.com";
var request = new XMLHttpRequest();
request.onload = function() {
var state = this.readyState;
var responseCode = request.status;
console.log("request.onload called. readyState: " + state + "; status: " + responseCode);
if (state == this.DONE && responseCode == 200) {
var responseData = this.responseText;
alert("Success: " + responseData.length + " chars received.");
}
};
request.error = function(e) {
console.log("request.error called. Error: " + e);
};
request.onreadystatechange = function(){
console.log("request.onreadystatechange called. readyState: " + this.readyState);
};
request.open("GET", url);
request.send(null);
};
Я тестирую это в последнем выпуске Firefox (только что обновленном сегодня). Строка журнала в onload
никогда не печатается, и точка останова, которую я установил в первой строке, никогда не попадает. Однако onreadystatechange
функция вызывается дважды, и HTTP запрос действительно сделан. Вот что показывает консоль firebug:
request.onreadystatechange called. readyState: 1
GET http://www.google.com/ 302 Found 174ms
request.onreadystatechange called. readyState: 4
NS_ERROR_FAILURE: Failure
request.send(null);
есть ошибка в блоке send
линии. Я попытался изменить его на request.send()
с идентичным результатом.
сначала я подумал, что это может быть браузер, пытающийся предотвратить XSS, поэтому я переместил свою страницу драйвера html в экземпляр Tomcat в моей машине dev, но результат тот же.
гарантируется ли вызов этой функции? Как я уже сказал выше, это часто можно увидеть в большинстве учебников, но с другой стороны в страница спецификации W3C, фрагмент hello world использует onreadystatechange
вместо:
function processData(data) {
// taking care of data
}
function handler() {
if(this.readyState == this.DONE) {
if(this.status == 200 &&
this.responseXML != null &&
this.responseXML.getElementById('test').textContent) {
// success!
processData(this.responseXML.getElementById('test').textContent);
return;
}
// something went wrong
processData(null);
}
}
var client = new XMLHttpRequest();
client.onreadystatechange = handler;
client.open("GET", "unicorn.xml");
client.send();
он проверяет readyState == this.DONE
. DONE
имеет значение 4, которое я вижу в своем журнале. Итак, если это была проблема, связанная с XSS, и браузер мешал мне установить соединение с другим доменом, то почему фактическое соединение выполнено и получен статус DONE???
PS: Да, я знаю, что есть мощные библиотеки, чтобы сделать это легко, но я все еще JavaScript noob, поэтому я хотел бы сначала понять низкий уровень.
обновление:
Я изменил URL-адрес на один внутри моего домена (localhost), и ошибка исчезла, но onload
функция по-прежнему не вызывается. Проверено в IE8 и не работает. Протестировано в Chrome и работает. Как это?
обновление 2:
Снова проверил в Firefox, и теперь он работает. Вероятно, старая страница все еще была кэширована, поэтому я не мог ее заметить сейчас. Все еще не удается в IE8, я попытаюсь протестировать его в более новой версии.
2 ответов
похоже, что это действительно проблема XSS, и Firefox блокирует onload
звонок. Я все еще не могу понять, почему сетевой запрос http фактически выполнялся и onreadystatechange
был с DONE
readyState.
Я изменил URL на другой в том же домене, и теперь он работает в Firefox (после некоторых ложных попыток, связанных с кэшем) и в Chrome. Он по-прежнему не работает в IE8, несмотря на официальные документы скажите, что он поддерживается. Я нашел это так ответ который утверждает обратное. Похоже на onload
функция является более современным методом удобства, и старый способ проверки результата использует onreadystatechange
вместо.
Я думаю, что я приму этот ответ в качестве решения, если не будет предоставлен более подробный ответ.
IE имеет другой метод для создания xmlhttprequest.
function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// Check if the XMLHttpRequest object has a "withCredentials" property.
// "withCredentials" only exists on XMLHTTPRequest2 objects.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// Otherwise, check if XDomainRequest.
// XDomainRequest only exists in IE, and is IE's way of making CORS requests.
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// Otherwise, CORS is not supported by the browser.
xhr = null;
}
return xhr;
};
же эта статья:https://www.html5rocks.com/en/tutorials/cors/