объект 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/