11

私はこの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関数は2回呼び出され、実際には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);

行にエラーがありますsendrequest.send()同じ結果になるように変更してみました。

最初は、これがXSSを阻止しようとしているブラウザーである可能性があると考えたため、HTMLドライバーページを開発マシンのTomcatインスタンスに移動しましたが、結果は同じです。

この関数は呼び出されることが保証されていますか?上で述べたように、ほとんどのチュートリアルで見られるのが一般的ですが、一方、W3C仕様ページでは、helloworldスニペットは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.DONEDONE値は4です。これは、ログに表示されるものです。したがって、これがXSS関連の問題であり、ブラウザが別のドメインへの接続を妨げていた場合、実際の接続が確立され、DONEステータスが受信されるのはなぜですか?

PS:はい、これを簡単に行うための強力なライブラリがあることは知っていますが、私はまだJavaScriptの初心者なので、まず低レベルを理解したいと思います。


更新:
URLをドメイン内のURL(localhost)に変更しましたが、エラーはなくなりましたが、onload関数はまだ呼び出されていません。IE8でテストされ、動作しません。Chromeでテストされ、動作します。どのようだ?


更新2:
Firefoxで再度テストしたところ、動作するようになりました。おそらく古いページはまだキャッシュされていたので、すぐに気付かなかったのです。IE8でもまだ失敗しているので、新しいバージョンでテストしてみます。

4

3 に答える 3

11

それは確かに XSS の問題であり、Firefox がonload呼び出しをブロックしていたようです。http ネットワーク リクエストが実際に実行され、 readyStateonreadystatechangeで呼び出された理由をまだ理解できません。DONE

URL を同じドメイン内の別の URL に変更したところ、Firefox (キャッシュ関連の誤った試みの後) と Chrome で機能するようになりました。公式ドキュメントにはサポートされていると書かれていますが、IE8 ではまだ動作しません。私はこのSOの答えを見つけました。関数はより現代的なonload便利な方法であり、結果を確認する古い方法がonreadystatechange代わりに使用されているようです。

より詳細な回答が提供されない限り、この回答を解決策として受け入れると思います。

于 2013-02-06T13:00:16.280 に答える