Seite bei Formular mit "post" nicht neu laden mit XMLHttpRequest

Dragosius

Erfahrenes Mitglied
Hallo zusammen,

ich habe momentan folgendes Formular:
HTML:
    <form action="<?php echo filter_input(INPUT_SERVER, 'REQUEST_URI'); ?>" method="post">
        <input type="text" name="shout" style="width:98%" maxlength="200"><br />
        <input type="submit" name="butshout" value="Senden">
    </form>

Dies wird folgendermaßen ausgewertet:
PHP:
    // Neuer Eintrag in die Shoutbox
    $shoutEintrag = filter_input(INPUT_POST, 'shout', FILTER_SANITIZE_STRING);
    if( !empty(filter_input(INPUT_POST, 'butshout', FILTER_SANITIZE_STRING)) && !empty($shoutEintrag) ) {
        $alteEintraege = mysqli_fetch_assoc(sqlQuery("SELECT `text` FROM `shoutbox` WHERE `user_id`='".$userId."' ORDER BY `id` DESC LIMIT 0,1"));
        if( $alteEintraege['text'] != $shoutEintrag ) { // Überprüfung, ob der gleiche Inhalt bereits abgesendet wurde
            sqlQuery("INSERT INTO `shoutbox` (`text`,`datum`,`user_id`) VALUES ('".mysqli_real_escape_string($db_link, $shoutEintrag)."',NOW(),'$userId')");
        }
    }

Es handelt sich hierbei um eine Shoutbox.
Wie kann ich es denn (mit XMLHttpRequest) lösen, dass nach dem Absenden die Webseite nicht neu geladen wird?

Des Weiteren würde ich es gerne noch so realisieren, dass gleichzeitig der Inhalt der Shoutbox neu geladen wird, damit man seinen Eintrag sofort sieht.
Ich habe bereits eine Funktion, welche mir die Shoutbox regelmäßig neu lädt:
Javascript:
setInterval(function() {
    hole_shoutbox();
},10000);

Kann mir da jemand weiterhelfen?


Vielen Dank
 
Warum willst Du es denn mit XMLHttpRequest lösen, in deinem anderen Thread benutzt Du doch $.ajax, das wäre wesentlich einfacher und übersichtlicher zu handhaben?
 
Ich würde dabei so vorgehen: Die Datei shoutbox.php hast Du ja schon. Beim Ajax-Aufruf dieser Datei würde ich den Text als POST-Parameter mitgeben, wobei dieser Parameter optional wäre. Das PHP würde dann den neuen Text in die DB eintragen, wenn der Parameter vorhanden ist und in jedem Fall die Inhalte auslesen, wie Du es schon hast, und zurück liefern. Dann kannst du die Datei für beides einsetzen: Posten eines Textes mit Parameter und zyklisches Holen der Inhalte mit setIntverval().
 
Ok theoretisch habe ich es nun glaube ich verstanden, aber könntest du mir eventuell noch helfen, wie ich das am Besten umsetzen kann?
 
OK, wenn Du das PHP-Skript mit Ajax aufrufst, brauchst Du dieses butshout nicht mehr. Sonst kannst Du alles so beibehalten und fügst am Ende das Auslesen der Einträge hinzu, genau so wie Du es schon hast:
PHP:
    // Neuer Eintrag in die Shoutbox
    $shoutEintrag = filter_input(INPUT_POST, 'shout', FILTER_SANITIZE_STRING);
    if( /*!empty(filter_input(INPUT_POST, 'butshout', FILTER_SANITIZE_STRING)) &&*/ !empty($shoutEintrag) ) {
        $alteEintraege = mysqli_fetch_assoc(sqlQuery("SELECT `text` FROM `shoutbox` WHERE `user_id`='".$userId."' ORDER BY `id` DESC LIMIT 0,1"));
        if( $alteEintraege['text'] != $shoutEintrag ) { // Überprüfung, ob der gleiche Inhalt bereits abgesendet wurde
            sqlQuery("INSERT INTO `shoutbox` (`text`,`datum`,`user_id`) VALUES ('".mysqli_real_escape_string($db_link, $shoutEintrag)."',NOW(),'$userId')");
        }
    }
    // hier das Auslesen der Eintraege hinzu fuegen, so wie Du es schon hast.

Dann statt des Submit type="button" verwenden und darauf einen Eventlistener registrieren, der beim Klick den Text abschickt:
Code:
        <input type="text" id="shout" style="width:98%" maxlength="200"><br />
        <input type="button" id="butshout" value="Senden">
<script>
    function doShout(txt) {
          // Daten vorbereiten: Nur wenn ein Text vorhanden ist, diesen eintragen,
          // andernfalls bleibt das Objekt leer
          if (txt) let data = {shout: txt};
          else let data = {};
          $.ajax({
            type: 'POST',
url: 'shoutpox.php',
data: data, // Daten uebergeben
success: function(data1){
$('#shoutbox').html(data1);
}
         });
   }

    $('#butshout').on('click', (event) => {
        const txt = $('#shout').text();
        doShout(txt);
    });
    setInterVal(doShout, 5000);
</script>
(irgend wie zerstört das Forum die Einrückungen)
ungetestet
 
Das funktioniert leider noch nicht.
Warum genau muss ich denn bei der URL shoutbox.php angeben?
Das ist doch nur die Datei, welche die Einträge anzeigt.

Einbindung im Template der Shoutbox:
HTML:
<div style="width:100%;" id="box">
    <div style="width:100%;" id="shoutbox">
    </div>
 
    <input type="text" id="shout" style="width:98%" maxlength="200"><br />
    <input type="button" id="butshout" value="Senden">&nbsp;<a href="index.php?info=shoutbox-archiv">[Archiv]</a>
    <script>
    function doShout(txt) {
        // Daten vorbereiten: Nur wenn ein Text vorhanden ist, diesen eintragen,
        // andernfalls bleibt das Objekt leer
        if (txt) let data = {shout: txt};
        else let data = {};
        $.ajax({
            type: 'POST',
            url: 'index.php',
            data: data, // Daten uebergeben
            success: function(data1){
                $('#shoutbox').html(data1);
            }
        });
    }

    $('#butshout').on('click', (event) => {
        const txt = $('#shout').text();
        doShout(txt);
    });
    setInterVal(doShout, 5000);
</script>
</div>

Auswertung in der index.php, wo das Template von der Shoutbox eingebunden ist:
PHP:
    // Neuer Eintrag in die Shoutbox
    $shoutEintrag = filter_input(INPUT_POST, 'shout', FILTER_SANITIZE_STRING);
    if( /*!empty(filter_input(INPUT_POST, 'butshout', FILTER_SANITIZE_STRING)) &&*/ !empty($shoutEintrag) ) {
        $alteEintraege = mysqli_fetch_assoc(sqlQuery("SELECT `text` FROM `shoutbox` WHERE `user_id`='".$userId."' ORDER BY `id` DESC LIMIT 0,1"));
        if( $alteEintraege['text'] != $shoutEintrag ) { // Überprüfung, ob der gleiche Inhalt bereits abgesendet wurde
            sqlQuery("INSERT INTO `shoutbox` (`text`,`datum`,`user_id`) VALUES ('".mysqli_real_escape_string($db_link, $shoutEintrag)."',NOW(),'$userId')");
            hole_shoutbox();
        }
    }


Aktuell wird die Nachricht noch nicht in der Datenbank gespeichert, also noch nicht abgesendet.
 
Zuletzt bearbeitet:
Warum genau muss ich denn bei der URL shoutbox.php angeben?
Das ist doch nur die Datei, welche die Einträge anzeigt.
Musst Du nicht aber das ist meine Empfehlung: Eine einzige Datei verwenden, die sowohl den Eintrag erledigt als auch das Auslesen der Einträge.
Möglicher Weise hat deine PHP-Datei für das Eintragen aber einen anderen Namen, dann musst Du den nehmen.

In deinem PHP sehe ich das hole_shoutbox() - wenn Du damit die Javascript-Datei meinst, kann das nicht funktionieren. Du musst das PHP, das Du in dem anderen Thread hast für das Auslesen und echo der Tabelle dort hin kopieren.

Allerdings wenn shoutbox.php die Einträge anzeigt, kannst Du auf Kopieren verzichten und statt dessen die Datei inkludieren:
Code:
    // Neuer Eintrag in die Shoutbox
    $shoutEintrag = filter_input(INPUT_POST, 'shout', FILTER_SANITIZE_STRING);
    if( /*!empty(filter_input(INPUT_POST, 'butshout', FILTER_SANITIZE_STRING)) &&*/ !empty($shoutEintrag) ) {
        $alteEintraege = mysqli_fetch_assoc(sqlQuery("SELECT `text` FROM `shoutbox` WHERE `user_id`='".$userId."' ORDER BY `id` DESC LIMIT 0,1"));
        if( $alteEintraege['text'] != $shoutEintrag ) { // Überprüfung, ob der gleiche Inhalt bereits abgesendet wurde
            sqlQuery("INSERT INTO `shoutbox` (`text`,`datum`,`user_id`) VALUES ('".mysqli_real_escape_string($db_link, $shoutEintrag)."',NOW(),'$userId')");
            hole_shoutbox();
        }
    }
    // Shoutbox lesen und in einer HTML-Tabelle ausgeben
    include 'shoutbox.php';
 
Zuletzt bearbeitet:
Danke für den Tipp, nur das ist ja schon ein Fehler weiter, da ich aktuell ja noch nicht Mal zum INSERT-Statement komme.
Aktuell werden die neuen Einträge noch nicht in die Datenbank geschrieben und ich habe um ehrlich zu sein keine Ahnung, woran das liegt.
 
Wenn etwas nicht funktioniert und man nicht weiß warum, muss man ins Debugging einsteigen. Als erstes die Console beobachten, ob Fehlermeldungen kommen. Im PHP-Skript dieses an den Anfang schreiben:
Code:
ini_set('display_errors', '1');
error_reporting(E_ALL);
dann werden Fehlermeldungen ausgegeben. Diese werden ja über Ajax zurück geliefert und auf der HTML-Seite angezeigt.
Daraus sollten sich Hinweise ergeben wo der Fehler liegt.
 
Zuletzt bearbeitet:
Danach könntest du vieleicht auch noch schaun was im $_POST steht
PHP:
ini_set('display_errors', '1');
error_reporting(E_ALL);
echo "<pre>";
print_r($_POST);// oder $_GET
echo "</pre>";
 
Zurück