Der Max: xmlHttpRequest.open - Verständnisfrage

Hallo Forum,

ich habe folgendes kuriose Verhalten, dass ich nicht verstehe:

ich habe ein xmlHttpRequest-Objekt (this.xmlhttp im Beispiel) und eine log-Methode, die mir Debuginformationen in ein DIV loggt. In einer "send"-Methode steht dieses Stück code:

...
  this.xmlhttp.onreadystatechange = function() { mycallback; }

log('pre-open');
  this.xmlhttp.open('POST', url);
  log('post-open');

this.xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
  ...
  this.xmlhttp.send(query);
  ...

Nachdem ich die beiden "log"-Anweisungen eingebaut hatte, habe ich festgestellt, dass "post-open" erst nach der Rückkehr aus der "callback"-Methode ausgegeben wird. Bisher bin ich davon ausgegangen, dass der Request erst mit dem "send"-Befehl abgesetzt wird, nicht schon beim "open".

Kann mich jemand vielleicht erleuchten oder mir eine passende Internet-Ressource zur Hand geben, die die Funktionsweise des xmlHttpRequests ganz genau erklärt?

Bisher habe ich mir http://developer.apple.com/internet/webcontent/xmlhttpreq.html durchgelesen, ist mir aber noch zu ungenau bzw. zu wenig detailliert...

Vielen Dank und einen schönen Gruß!
Maxe

  1. hi,

    Bisher bin ich davon ausgegangen, dass der Request erst mit dem "send"-Befehl abgesetzt wird, nicht schon beim "open".

    Ja, das ist korrekt.

    Es gibt aber verschiedene "readystates", die alle den Aufruf der Handlerfunktion aufrufen; Siehe bspw. http://developer.mozilla.org/de/docs/AJAX:Getting_Started#Schritt_2_.E2.80.93_.22Bittesch.C3.B6n.21.22_oder_Verarbeiten_der_Antwort_des_Servers.

    Wenn du also in dieser Funktion erst dann reagieren willst, wenn der Status 4 (vollständig) erreicht ist - dann musst du die Eigenschaft .readyState deines Requestobjektes erst noch auf diesen Wert abfragen.

    gruß,
    wahsaga

    --
    /voodoo.css:
    #GeorgeWBush { position:absolute; bottom:-6ft; }
    1. Hi zurück!

      Es gibt aber verschiedene "readystates", die alle den Aufruf der Handlerfunktion aufrufen; Siehe bspw.

      Ja, soweit hatte ich das schon verstanden. Was mich wundert, ist dass die asynchrone Abarbeitung schon beim "open" und nicht erst beim "send" beginnt:

      "Zur Erinnerung: beim Abschicken des Requests wurde der Name einer JavaScript-Funktion mitgegeben, welche die Antwort abarbeiten soll."

      Beim _Abschicken_ schreiben die da. In meinem Fall geschieht das aber eben schon vor dem "Abschicken" == "send".

      Ich bin völlig verwirrt...
      Danke + Grüsse,
      Maxe

      1. hi,

        "Zur Erinnerung: beim Abschicken des Requests wurde der Name einer JavaScript-Funktion mitgegeben, welche die Antwort abarbeiten soll."

        Beim _Abschicken_ schreiben die da. In meinem Fall geschieht das aber eben schon vor dem "Abschicken" == "send".

        Das darfst du wohl nicht so wörtlich nehmen.

        Ab dem Zeitpunkt, wo du die Handler-Funktion definierst, springt sie bei einer Änderung des Status auch an.

        gruß,
        wahsaga

        --
        /voodoo.css:
        #GeorgeWBush { position:absolute; bottom:-6ft; }
        1. Lieber wahsaga,

          Das darfst du wohl nicht so wörtlich nehmen.

          Ab dem Zeitpunkt, wo du die Handler-Funktion definierst, springt sie bei einer Änderung des Status auch an.

          ja, genauso ist es. Ich bin endlich auf eine vernünftige Erläuterung gestossen:

          http://ajaxpatterns.org/XMLHttpRequest_Call

          "The XMLHttpRequest's readyState always reflects the current point in the call's lifecycle. When the object is born, it's at 0. After open() has been called, it's 1. This continues until the response is back, at which point the value is 4.

          So, to catch the response, you need to watch for a readyState of 4. That's an easy chore, because XMLHttpRequest fires readystatechange events. You can declare a callback function using the onreadystatechange field. The callback will then receive all state changes. The states below 4 aren't especially useful and are somewhat inconsistent across browser types anyway. So most of the time, all we're interested in is state 4, when the response is complete. "

          Aber mir fehlt noch ein Puzzlestück: wenn ich nicht auf die "states below 4" setzen soll, wie weiß ich denn eigentlich, ob der Server _überhaupt_ eine Antwort gegeben hat? Ich möchte feststellen, ob der Server vielleicht nicht erreichbar ist (und prüfe das über einen Timeout). Also 0 + 1 werden scheinbar schon vom Client selbst geschmissen, die 4 kommt in jedem fall nur dann, wenn der Server geantwortet hat. Aber was ist mit 2 + 3? Was ist mit den Inkonstistenzen der Browser? Ich frage mich ja, warum so eine zentrale Technologie die das Web gerade umwälzt nicht besser dokumentiert ist. Nicht mal in meinem teuren "Ajax in Action"-Buch finde ich was Genaueres darüber :(

          Beste Grüsse, Max

          1. hi,

            Aber mir fehlt noch ein Puzzlestück: wenn ich nicht auf die "states below 4" setzen soll, wie weiß ich denn eigentlich, ob der Server _überhaupt_ eine Antwort gegeben hat?

            Du zeihst den Umkehrschluss aus "er hat während einer definierten Zeitspanne _nicht_ so geantwortet, dass der readystate 4 erreicht wurde".

            Ich möchte feststellen, ob der Server vielleicht nicht erreichbar ist (und prüfe das über einen Timeout).

            Na also, du weißt doch offenbar schon, wie's geht.

            Also 0 + 1 werden scheinbar schon vom Client selbst geschmissen, die 4 kommt in jedem fall nur dann, wenn der Server geantwortet hat. Aber was ist mit 2 + 3?

            In wie fern sollten die für dich interessant sein?
            Die spielen sich nach meinem Verständnis noch rein auf dem Client ab - haben also mit der Erreichbarkeit des Servers wenig bis gar nichts zu tun.

            Was ist mit den Inkonstistenzen der Browser?

            Die halte ich hier für nicht relevant.

            gruß,
            wahsaga

            --
            /voodoo.css:
            #GeorgeWBush { position:absolute; bottom:-6ft; }
            1. Hallo!

              Aber mir fehlt noch ein Puzzlestück: wenn ich nicht auf die "states below 4" setzen soll, wie weiß ich denn eigentlich, ob der Server _überhaupt_ eine Antwort gegeben hat?

              Du zeihst den Umkehrschluss aus "er hat während einer definierten Zeitspanne _nicht_ so geantwortet, dass der readystate 4 erreicht wurde".

              Ok, so klar war das aber bisher noch nicht. Angenommen der Server würde antworten und die Antwort würde in einem readyState 3 resultieren, dann würde ich sdem User _fälschlicherweise_ mitteilen, dass der Server nicht erreichbar ist. Wenn aber _nur_ der readyState 4 eine Antwort vom Server signalisiert ist alles klar :)

              Aber so ganz sicher bist Du da ja auch nicht:
              "Die spielen sich nach meinem Verständnis noch rein auf dem Client ab"

              Aber als Quick-Hack ist das jetzt erstmal ausreichend...

              Herzlichen Dank jedenfalls für Deine Hilfe und Dein Ohr!
              Max

              1. hi,

                Ok, so klar war das aber bisher noch nicht. Angenommen der Server würde antworten und die Antwort würde in einem readyState 3 resultieren, dann würde ich sdem User _fälschlicherweise_ mitteilen, dass der Server nicht erreichbar ist.

                Nach dem Readystate 3 dürfte es m.E. nur bei sehr langsamer Verbindung oder/und großen Datenmengen einen längeren Zeitraum dauern, bis State 4 eintritt:

                "3 Interactive - Downloading, responseText holds the partial data."

                Die Antwort ist also am Eintrudeln, aber eben noch nicht vollständig da.

                Wenn aber _nur_ der readyState 4 eine Antwort vom Server signalisiert ist alles klar :)

                3 signalisiert "Server ist 'am Antworten'", 4 besagt "Anwort des Servers ist komplett eingetroffen".

                Da die Readystates 3 und 4 laut http://www.quirksmode.org/blog/archives/2005/09/xmlhttp_notes_r_2.html von allen (getesteten ...) Browsern korrekt signalisiert werden, sehe ich hier also kein Problem, zu entscheiden ob der Server innerhalb einer definierten Zeitspanne _gar nicht_ geantwortet hat.

                Aber so ganz sicher bist Du da ja auch nicht:
                "Die spielen sich nach meinem Verständnis noch rein auf dem Client ab"

                Sorry, das war auf 1 und 2 bezogen, die sich ja auf send() beziehen - und das ist m.E. noch der rein clientseitige Teil des ausgehenden Requests.

                gruß,
                wahsaga

                --
                /voodoo.css:
                #GeorgeWBush { position:absolute; bottom:-6ft; }
                1. Puh, jetzt scheint endlich alles zu funktionieren. Ich frage Status 3 ODER 4 ab und wenn ja, setzte ich die timeout-Variable wieder zurück.

                  Vielen Dank für Deine Geduld!
                  Mit besten Grüssen,
                  Max

          2. Hallo,

            Ich frage mich ja, warum so eine zentrale Technologie die das Web gerade umwälzt nicht besser dokumentiert ist.

            Dann weiss du jetzt, dass es keine so zentrale Technologie ist.

            Grüße
            Thomas