简体   繁体   中英

Javascript function only works if there's an alert

This code executes post.php :

function SubmitForm() {
    var input = $("#input").val();
    var user = "anon";
    $.post("post.php", {input: input, user: user}, function(data) {});
    alert("hello");
}

But if I remove a line, this doesn't:

function SubmitForm() {
    var input = $("#input").val();
    var user = "anon";
    $.post("post.php", {input: input, user: user}, function(data) {});
}

Seems irrational, but why is this happening?

The PHP which the JS should call inserts some values into the database:

<?php


$dbhost = "xxx";
$dbname = "xxx";
$dbuser = "xxx";
$dbpass = "xxx";

// Create connection
$con = mysqli_connect($dbhost, $dbuser, $dbpass);

// Check connection
if (!$con) {
    die("Database connection failed: " . mysqli_error());
}

// Select database
$db_select = mysqli_select_db($con, $dbname);

// Check selection
if (!$db_select) {
    die("Database selection failed: " . mysqli_error());
}

$message = $_POST["input"];
$user = $_POST["user"];
echo $message;
echo $user;

$query = "INSERT INTO posts (user, message) VALUES ('$user', '$message')";
mysqli_query($con, $query);
?>

Your problem is that this function is being called in an onsubmit / onclick event handler. AJAX is asynchronous, meaning it runs in the background. When you call $.post , the code continues on and the callback is called at some point in the future.

What is happening is that the form is being submitted, so the page is being redirected. This is happening before the AJAX call finishes. The alert pauses the browser, so it gives the AJAX call a chance to finish.

You need to block browser from performing the "default" action.

<input type="submit" class="button" id="button_post" value="POST" onclick="SubmitForm(); return false;">

PS I suggest that you bind event handlers in JavaScript versus inline handlers.

<input type="submit" class="button" id="button_post" value="POST">

<script>
$(function(){
    $('#button_post').click(function(e){
        e.preventDefault();
        SubmitForm();
    });
});
</script>

It probably does work (or the POST is failing in both cases).

To see whether it really works, your alert should be inside of the callback - as that is the code that will run if the request succeeds.

function SubmitForm() {
    var input = $("#input").val();
    var user = "anon";
    $.post("post.php", {input: input, user: user}, function(data) {
        alert(data);
    });
}

It is always worth firing up your browser's developer tools to see the network request and check that it works.

This is almost certainly related to the fact that $.post is executed asynchronously and you're not properly accounting for that. The alert is pausing execution, which is buying you some time for the post to finish, so that anything that needs its result later might actually have access to that result. Removing the alert removes this pause and breaks anything that was relying on this side-effect. (In other words, something that needs the result of post is executing before the post has finished.)

You should perform any action that relies on the results of the $.post inside the callback that is passed to it:

$.post("post.php", {input: input, user: user}, function(data) {
    // do anything that relies on this post here
});

You say in a comment that you have:

<input type="submit" class="button" id="button_post" value="POST" onclick="SubmitForm();">

In that case, the form will get posted by the normal means. When you have an alert, the ajax call is able to succeed, but without the alert, the normal form submission probably prevents the ajax call.

You should either change the button so it is not a "submit" button:

<input type="button" ...

Or prevent the normal form submission by returning false in the "onclick":

<input ... onclick="SubmitForm(); return false;">

The easiest way would be run your jquery after the DOM has finished loaded. I also faced similar problem. Just add the function to be called inside:

 $(window).load(function(){
    // your function here. 
 });

As Rocket Hazmat mentioned, many puzzling issues when your code is awaiting results from Ajax calls come from the asynchronous mode . The problem comes from the fact that the code goes on before the Ajax query completed.

Using the synchronous mode forces waiting the answer from the Ajax call. When using jQuery, jQuery.ajax() supports setting the async option to false: async: false (instead of the default: true ).

Some libraries have methods which forgot the to implement the possibility of performing synchronous calls. As a "silent" alternative to adding calls like alert(" "); , a possible workaround in such case is adding a setTimeout() that triggers something silent, like writing something to the console. It is not "clean" code but can be useful. More details here: https://stackoverflow.com/a/49835054

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM