koellsch: Problem mit Datanbankabfrage per AJAX

Moin zusammen,
ich versuche mir im Moment eine Datenbankabfrage mit AJAX zu basteln. Die Abfrage mit PHP funktioniert ohne Probleme, nur die Javascriptfunktion macht nicht das, was sie soll. Es soll überprüft werden, ob eine bestellte Menge noch in der Datenbank vorhanden ist oder nicht.

Die Funktion sieht folgendermaßen aus:

function checkquant(){  
	count = 0;  
	xmlget = getXMLHTTP();  
	//xmlget.overrideMimeType('text/xml; charset=ISO-8859-1');  
	xmlget.open("GET", "var/config.php?action=checkquant");  
	xmlget.onreadystatechange = function(){  
		if ( xmlget.readyState == 4 && xmlget.responseText) {  
			var status = xmlget.responseText.split(".");  
			for (var t = 0; t < status.length; t++) {  
				if(status[t] == 1) {  
					document.getElementById('hint_'+t).innerHTML = 'Meldung';  
					count++;  
				}  
			}  
		}  
	}  
	xmlget.send(null);  
	if(count >= 1) return false;  
	if(count == 0) return true;  
}

Die Funktion getXMLHTTP() erzeugt die XMLHTTP-Instanz.

Die PHP Funktion in der config.php gibt eine Antwort in der Form 1.0.1.1, je nachdem, wie viele Artikel bestellt werden und ob die Menge vorhanden ist ( 0 ) oder nicht ( 1 ).
Wenn die Menge nicht vorhanden ist, soll in einem Div eine Meldung angezeigt werden. Wenn alles vorhanden ist, solls weiter gehen. Dafür wollte ich eigentlich die count Variable benutzen, allerdings gibt die Funktion immer true zurück. Erst, wenn ich den Befehl count++ hinter die if-Schleife setze, funktioniert das Ganze.

Da ich mich mit Javascript nicht so gut auskenne, hoffe ich, dass ihr mir helfen könnt.

Gruß
koellsch

  1. Hi,

    Dafür wollte ich eigentlich die count Variable benutzen, allerdings gibt die Funktion immer true zurück.

    Das liegt daran, dass du einer von den vielen Anfängern bist, die sich überhaupt nicht klar gemacht haben, wofür das erste A in AJAX steht.

    MfG ChrisB

    --
    RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
    1. Hi ChrisB,

      Ja, das stimmt wohl.
      Hab mir die open-Methode des XMLHttpRequest Objekts mal genauer angeguckt und gesehen, dass man da die Synchronisation einstellen kann.
      Das Ganze auf Synchron gestellt und jetzt gehts.

      Gruß
      koellsch

      1. Hi,

        Hab mir die open-Methode des XMLHttpRequest Objekts mal genauer angeguckt und gesehen, dass man da die Synchronisation einstellen kann.

        Sollte man aber nur in Sonderfällen machen - weil solche Requests auch das UI des Browsers blockieren können.

        Das Ganze auf Synchron gestellt und jetzt gehts.

        Asynchron richtig machen wäre die bessere Wahl.

        MfG ChrisB

        --
        RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
        1. Sollte man aber nur in Sonderfällen machen - weil solche Requests auch das UI des Browsers blockieren können.

          Hab ich mir schon irgendwie gedacht, dass das nicht ganz optimal ist.

          Asynchron richtig machen wäre die bessere Wahl.

          Wäre hilfreich, wenn du mir da einen Tipp geben könntest. Hab auf dem Gebiet nicht wirklich Erfahrung.

          Gruß
          koellsch

  2. Hi!

    Da ich mich mit Javascript nicht so gut auskenne, hoffe ich, dass ihr mir helfen könnt.

    Das Duerfte sich wohl nicht nur auf Javascript beziehen. Was soll denn eine If-Schleife sein? ;)

    Du musst, wie ChrisB schon erwaehnte, das Asynchrone richtig machen.

    Im Moment hast Du folgendes:

    XMLHTTP Object erstellen
    Request abschicken
    Wenn Antwort kommt
     {
      mach zeug
     }
    verarbeite Ergebnis von Zeug
    irgendwann kommt antwort
    Zeug wird gemacht

    selbst ohne Programmierkenntnisse sollte man merken, dass da in der Reihenfolge was nicht stimmt. Was Du machst:

    Eine Frau moechte kuchen backen, dafuer fehlt ihr Milch.
    Sie schickt ihren Mann los, Milch kaufen.
    Sie macht den Teig und schiebt ihn in den Ofen.
    Der Mann kommt mit der Milch nach Hause.

    --
    Vergesst Chuck Norris.
    Sponge Bob kann unter Wasser grillen!
    1. Hi,

      Das Duerfte sich wohl nicht nur auf Javascript beziehen. Was soll denn eine If-Schleife sein? ;)

      Ich hab gewusst, dass da einer meckern wird. Habs dann aber bei der Formulierung gelassen. Mir ist schon klar, dass das keine Schleife ist ;)

      XMLHTTP Object erstellen
      Request abschicken
      Wenn Antwort kommt
      {
        mach zeug
      }
      verarbeite Ergebnis von Zeug
      irgendwann kommt antwort
      Zeug wird gemacht

      Ich hab diese Abfolge aus einem Tutorial übernommen und hab gedacht, dass das so passt.

      Meiner Meinung nach ist die Abfolge doch so:

      XMLHTTP Object erstellen
      Verbindung zum Server aufbauen
      Wenn Daten übertragen wurden
      {
      Verarbeite die Daten
      }
      Schließe die Verbindung
      Frage Variable ab

      Die Verarbeitung der Daten klappt auch, nur nicht die Abfrage der Variablen.

      Kann auch sein, dass ich da einen Denkfehler drin habe.

      Gruß
      koellsch

      1. Hi,

        Meiner Meinung nach ist die Abfolge doch so:

        XMLHTTP Object erstellen
        Verbindung zum Server aufbauen
        Wenn Daten übertragen wurden
        {
        Verarbeite die Daten
        }
        Schließe die Verbindung
        Frage Variable ab

        Die Verarbeitung der Daten klappt auch, nur nicht die Abfrage der Variablen.

        Kann auch sein, dass ich da einen Denkfehler drin habe.

        Das ist genau der Fehler, der bereits dargestellt wurde.
        Die Verbindung ist asynchron, dein Skript läuft also weiter, nachdem der Request abgesetzt wurde und wartet nicht auf die Antwort.
        Die Antwort kommt irgendwann, zu diesem Zeitpunkt wird dann auch die Callback-Funktion aufgerufen. Verschiebe einfach den Teil deines Skriptes aus deinem Aufrufcode in die Callback-Funktion, welcher von der Antwort auf deinen Request abhängig ist.

        Bis die Tage,
        Matti

        1. »»Verschiebe einfach den Teil deines Skriptes aus deinem Aufrufcode in die Callback-Funktion, welcher von der Antwort auf deinen Request abhängig ist.

          Hab gedacht, die onreadystatechange-Funktion ist die Callback-Funktion, die dann aufgerufen wird?

          1. Hi,

            Verschiebe einfach den Teil deines Skriptes aus deinem Aufrufcode in die Callback-Funktion, welcher von der Antwort auf deinen Request abhängig ist.

            Hab gedacht, die onreadystatechange-Funktion ist die Callback-Funktion, die dann aufgerufen wird?

            Ich poste mal deinen JavaScript-Schnippsel von oben:

            function checkquant(){  
              count = 0;  
              xmlget = getXMLHTTP();  
              //xmlget.overrideMimeType('text/xml; charset=ISO-8859-1');  
              xmlget.open("GET", "var/config.php?action=checkquant");  
              xmlget.onreadystatechange = function(){  
                if ( xmlget.readyState == 4 && xmlget.responseText) {  
                  var status = xmlget.responseText.split(".");  
                  for (var t = 0; t < status.length; t++) {  
                    if(status[t] == 1) {  
                      document.getElementById('hint_'+t).innerHTML = 'Meldung';  
                      count++;  
                    }  
                  }  
                }  
              }  
              xmlget.send(null);  
              if(count >= 1) return false;  
              if(count == 0) return true;  
            }
            

            Ja, in onreadystatechange wird die callback-Funktion angegeben.
            Die letzten beiden Zeilen der Funktion checkquant() aber sind abhängig vom Ergebnis deiner Abfrage. Deswegen solltest du diese in die Callback-Funktion verschieben.

            In diesem Fall musst du deinen Code anderst gestalten. checkquant kann dir zu dem Zeitpunkt, an dem es beendet wird, bei einem asynchronen Request das gewünschte Ergebnis nicht liefern. Du musst deinen Rückgabewert anders setzen lassen. Üblich wäre z.B., checkquant eine callback-Funktion zu übergeben, welche aufgerufen wird, wenn dein Ergebnis diesen oder jenen Wert bekommt.

            Weitere Hinweise können wir dir aber nur geben, wenn du uns sagst, wie du checkquant zu nutzen gedenkst.

            Bis die Tage,
            Matti

            1. Üblich wäre z.B., checkquant eine callback-Funktion zu übergeben, welche aufgerufen wird, wenn dein Ergebnis diesen oder jenen Wert bekommt.

              Ok, sowas hab ich schon versucht, allerdings ohne Erfolg.

              Weitere Hinweise können wir dir aber nur geben, wenn du uns sagst, wie du checkquant zu nutzen gedenkst.

              Wie oben bereits geschrieben, brauche ich die Funktion lediglich für die Überprüfung, ob die bestellte Menge verfügbar ist.
              Die Funktion wird wie folgt aufgerufen:

              <form action="checkout_complete.html" onclick="return checkquant();" method="post">

              Ich brauche also nur den Wert "true" wenn die Menge vorhanden ist und "false" wenn nicht.

              Deshalb hab ich gedacht, es würde mehr Sinn machen, wenn die Funktion selber entweder false oder true ausgibt, wenn die Abfrage beendet ist.

              1. Hi,

                <form action="checkout_complete.html" onclick="return checkquant();" method="post">

                onclick auf einem form-Element? Bin gerade ein wenig irritiert, was dies für Nebeneffekte hat.

                Deshalb hab ich gedacht, es würde mehr Sinn machen, wenn die Funktion selber entweder false oder true ausgibt, wenn die Abfrage beendet ist.

                Andere Herangehensweise:
                Zum Einen könntest du checkout_complete.html so umschreiben, dass es dich zurückschickt, wenn dein Check nicht erfolgreich ist (Stichwort zum googlen: Affenformular), dies hätte gleichzeitig den Charme, dass du sogenannte TOCTTOU-Probleme los wirst, welche du momentan hast.

                Möglichkeit 2: du submittest dein Formular aus der callback-Funktion heraus, und rufst die Funktion an der Stelle auf, wo dein submit-Button jetzt ist (der danach nur noch ein Klick-Button mit dieser Funktion als Handler ist).

                Gibt noch einige andere Möglichkeiten, aber das wären soweit die einfachsten.

                Bis die Tage,
                Matti

                1. Hab mich für die 2. Möglichkeit entschieden.
                  Die Funktion sieht jetzt folgendermaßen aus:

                  function checkquant(){  
                  	count = 0;  
                  	 xmlget = getXMLHTTP();  
                  	//xmlget.overrideMimeType('text/xml; charset=ISO-8859-1');  
                  	xmlget.open("GET", "var/config.php?action=checkquant", true);  
                  	xmlget.onreadystatechange = function(){  
                      	if ( xmlget.readyState == 4 && xmlget.responseText) {  
                  			var status = xmlget.responseText.split(".");  
                              for (var t = 0; t < status.length; t++) {  
                  				if(status[t] == 1) {  
                  					document.getElementById('hint_'+t).innerHTML = 'Meldung';  
                  					count++;  
                  				}  
                  			}  
                  			if(count == 0) document.form.submit();  
                  		}  
                  	}  
                  	xmlget.send(null);  
                  }
                  

                  Funktioniert ohne Probleme.
                  Ist das denn jetzt so in Ordnung oder wäre die 1. Möglichkeit noch besser?

                  Gruß
                  koellsch