Sven: IE (6.0.2900.2180) macht doppelten submit.

hallo zusammen,

ich habe folgende javascript gebaut um einen doppelten submit der user duch schnelles klicken o.ä. auszuschließen. leider maht der ie (version 6.0.2900.2180) prinzipiell ein doppeltes submit. zeitgleich. kann da jamnd helfen?

das js:
function do_start(d,f) {
  var z = document.getElementById("BK").value;
  document.getElementById("BK").value = "1";
  if(z == 0) {
  eval("document."+d+".method = 'post'");
  eval("document."+d+".action = 'index.php?sess=1234567890&open=rechne.php&id="+f+"'");
  eval("document."+d+".target = '_top'");
  eval("document."+d+".submit()");
  } else {
  eval("document."+d+".number.value = '0'");
  alert('Bitte nur einmal klicken! Die Anfrage wird schon bearbeitet!');
  }

}

der form:
<form name="formular1" onsubmit="do_start('formular1',1);">
<input type="text" name="number" value="0" size="2">
<input type="submit" class="submit_box" value="Los!">
</form>
[VIEL HTML UND WEITERE FORMS....]
GANZ AM ENDE DANN:
<input id="BK" type="hidden" name="BK" value="0">

danke!
sven

  1. Tag Sven.

    ich habe folgende javascript gebaut um einen doppelten submit der user duch schnelles klicken o.ä. auszuschließen.

    Prinzipiell sollte man sowas *immer* durch einen serverseitigen Mechanismus abfangen.

    leider maht der ie (version 6.0.2900.2180) prinzipiell ein doppeltes submit. zeitgleich.

    Vermutlich nicht nur der IE.

    function do_start(d,f) {
      var z = document.getElementById("BK").value;
      document.getElementById("BK").value = "1";
      if(z == 0) {
      eval("document."+d+".method = 'post'");
      eval("document."+d+".action = 'index.php?sess=1234567890&open=rechne.php&id="+f+"'");
      eval("document."+d+".target = '_top'");
      eval("document."+d+".submit()");
      } else {
      eval("document."+d+".number.value = '0'");
      alert('Bitte nur einmal klicken! Die Anfrage wird schon bearbeitet!');
      }
    }

    Oje, so einen exzessiven und unnötigen Gebrauch von eval() habe ich lange nicht mehr gesehen. Sieh dir bitte zunächst die allgemeinen Regeln für den Zugriff auf Formulare an, dort insbesondere Schema 4.

    Im nächsten Schritt überlege genau, was dein Javascript macht:

    1. Prüfen, ob bereits versandt
    2a. Wenn nicht, setze das Formularziel ("action")
    2b. Wenn ja, Fehlermeldung
    3. Formular versenden

    Jetzt überlege, wann ein Script im else-Zweig landet: wenn das Formular bereits versandt wurde. Da der Versand über die gleiche Funktion erfolgt, *muss* zwangsläufig der erste Teil (if z == 0) bereits durchlaufen worden sein, dein Formular hat also sein Ziel erhalten. Aber du verhinderst nirgendwo in deiner JS-Funktion, dass das bereits versandte Formular nicht nochmal versandt wird, es wird stets versandt (siehe 3.). Dein Stichwort für die Problemlösung lautet "return true/false", siehe hierzu auch das Beispiel zu onsubmit.

    Siechfred

    1. Hi Siechfred,

      danke erstmal für die Promte Hilfe!
      Ich fang mal an ;-) :

      -- Ich prüfe Serverseitig, daß nicht race conditions entstehen, die sind abgefangen. requests werden nacheinander verarbeitet. gegen doppeltes submit kann ich ja sonst nichts tun, da es nicht ausgeschlossen ist die funktion oben mehrfach aufzurufen.

      -- Was ist an eval() schlecht? Ich habe leider keine andere Möglichkeit gefundend as dingens anslaufen zu bekommen in allen Browsern ohnen den eval() trick. Bin hier gerne für eine Erweiterung meines Wissens dankbar. ;-)

      -- zu 2.a / 2.b:
      Ich stehe etwas auf dem Schlauch. Das mach ich doch. Wenn Input Feld mit "ID BK == "1" dann mache kein Submit.

      -- zum System mit true/false
      ich erweitere also wie folgt:

      function do_start(d,f) {
        [...]
        if(z == 0) {

      [...]
        return true;

      } else {
        [...]
        return false;
        }

      }

      der form:
      <form name="formular1" onsubmit="return do_start('formular1',1);">
      [...]
      </form>
      [...]

      @afra:
      du meinst
      eval("document."+d+".sumbit.disabled = true"); ?!

      Generell:
      Ich verstehe halt immer noch nicht warum der Prozess 2mal gestartet wird. Ist es mein Code?!

      Danke und Gruß
      Sven

      1. -- Ich prüfe Serverseitig, daß nicht race conditions entstehen, die sind abgefangen. requests werden nacheinander verarbeitet. gegen doppeltes submit kann ich ja sonst nichts tun, da es nicht ausgeschlossen ist die funktion oben mehrfach aufzurufen.

        Doch, das kannst du mit Hilfe von Sessions, indem du serverseitig jeder Session ein "Formular versandt"-Flag mitgibst. Dann brauchst du grundsätzlich auch kein Javascript. Eine Session-ID hast du ja schon, wenn ich das richtig sehe.

        -- Was ist an eval() schlecht?

        Siehe http://forum.de.selfhtml.org/archiv/2004/9/t89570/#m535693, gleich mit Lösungsansatz für dein Problem.

        -- zu 2.a / 2.b:
        Ich stehe etwas auf dem Schlauch. Das mach ich doch. Wenn Input Feld mit "ID BK == "1" dann mache kein Submit.

        Nein, eben nicht: Wenn 1, dann Fehlermeldung. Das Formular wird auch in diesem Fall versandt.

        -- zum System mit true/false
        ich erweitere also wie folgt:
        [...]

        Ja, so sollte es funktionieren.

        Ich verstehe halt immer noch nicht warum der Prozess 2mal gestartet wird. Ist es mein Code?!

        Ja, insbesondere die damit verbundene Logik. Aber das Problem sollte jetzt klar sein, oder?

        Siechfred

  2. Hallo!

    Eigentlich hat Siechfred ja schon alles gesagt, aber es gäbe eine kleine kurze, halbwegs funktionierende Methode einen zweiten Submit abzufangen, der auch nicht so unschön wäre wie Du dies tust. Es würde doch völlig ausreichen den text auf dem Submitbutton onclick zu ändern und diesen dann zu disablen

    Schönen Gruß

    Afra

  3. Ich fang mal von hinten an, ein Formular braucht ein action Attribut http://www.w3.org/TR/html4/interact/forms.html#h-17.3

    Zumal mir auch nicht klar ist was du hier machst.

    <form name="formular1" onsubmit="do_start('formular1',1);">

    Das einzige was Variabel in der URL ist, ist die eins, d.h. action ist gleich "index.php?sess=1234567890&open=rechne.php&id=1"

    Also käme die ganze Sache erstmal ohne JS aus:
    <form action="index.php?sess=1234567890&open=rechne.php&id=1"
    method="post" target="_top">

    Was du mit dem input Feld BK bezweckst ist mir auch nicht ganz klar, das läßt sich sicher eleganter lösen.

    Struppi.

    1. nene ich hab leider x formulare. deswegen die ganze anstrengung. bei einem formular hätte ich den action parameter direkt untergebracht.

      das feld bk spert nach dem ersten sbumit jedes weitere submit. es wird also auf 1 gesetzt damit weiß ich ob schon abgeschickt wurde. eine art riegel also.

      1. Hallo Sven!

        Ich verstehe Deine komplizierte Denke immer noch nicht. Wenn DU den Button beim Submit nicht mehr klickbar machst, dann wirst Du sicherlich keine zwei Submits haben. Dann sparst Du dir diese ganze Riegel und eval Hampelei.

        Setze im Form Tag:

        <form action="" id="" onsubmit="submit_button.value='Bitte warten';submit_button.disabled=true;">

        Das ganze kannst DU auch auslagern. Das soll aber das System verdeutlichen.

        Schönen Gruß

        Afra

      2. nene ich hab leider x formulare. deswegen die ganze anstrengung. bei einem formular hätte ich den action parameter direkt untergebracht.

        aber was machen diue x- Formulare uind wie erzeugst du diese? Den JS Aufruf musst du ja auch jedesmal anders machen.

        das feld bk spert nach dem ersten sbumit jedes weitere submit. es wird also auf 1 gesetzt damit weiß ich ob schon abgeschickt wurde. eine art riegel also.

        Für das eine Formular oder alle?

        Im ersten Fall kannst du onsubmit dem Formular eine Eigenschaft geben.

        z.b. so:

        <form action="..."
        onsubmit="return is_submit(this);">

          
        function is_submit(form)  
        {  
             if(form.is_submit ) return false;  
             form.is_submit = true;  
             return true;  
        }
        

        Im zweiten Fall kannst du genau so gut ein globale Variabel nehmen und musst kein Formularfeld mißbrauchen.

        Struppi.