0

I can return a PHP value just fine to AJAX, but when I compare the value within the AJAX function it enters a secondary function even though it should not.

The following code does a post request to another PHP page (ping.php) to check if a url returns valid headers back. That result is returned back to AJAX in a simplified format ("success" or "nope"). I get the correct values in the console, but even with the failed count incremented it still enters the next function. why o' why o' why?

hello.php

<?php

echo "Hello World"; ?>
<html>
<head>
    
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

        
<script>

$(document).ready(function(){
  
  $('#form_post').on('submit', function(event){
    event.preventDefault();
    var count_error = 0;

    if($('#url').val() == '') {
      $('#url_error').text('URL is required');
      count_error++;
    } 
    else {
      $('#url_error').text('');
    }
      
    $.ajax({
      url: "ping.php",
      method: "POST",
      data: $(this).serialize(),
      beforeSend: function() {
        $('#process').css('display', 'block');
      },
      success: function(response) {
        if ($.trim(response) == "success") {
          console.log("success");
        } 
        else {
          console.log("failed");
          count_error++;
        }
      }
    });
      
    if(count_error == 0) {
      console.log("ok");
    }
  });
});
</script>
    
</head>

<body>
<html>

<div>
<form method="post" id="form_post">
<input type="text" name="url" id="url" class="my_form"/>
<span id="url_error" class="text-danger"></span>
<div class="form_display" align="left">
<input type="submit" name="form_post" id="form_post" class="my_form" value="form_post"/>
</div>
</form>
</div>
  
</body>
</html>

ping.php

<?php

if(isset($_POST["url"])) {
// $data = array(':url'  => trim($_POST["url"]));
    $data = trim($_POST["url"]);
} else {
    return;
}

$ping = $data;
$file_headers = @get_headers($ping);
if(!$file_headers || $file_headers[0] == 'HTTP/1.1 404 Not Found') {
    $exists = "false";
} else {
    $exists = "true";
}

if ($exists == "true") {

    echo "success";
    
} else {
    
    echo "nope";
}

If you happen to run the code somewhere then you can either put in a valid URL and submit the form (returning "success") or an invalid URL (returning "nope"). "ok" should only appear in the console if "success".

ADyson
  • 57,178
  • 14
  • 51
  • 63
ctfd
  • 338
  • 3
  • 14
  • Does this answer your question? https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call – Nick Jan 20 '21 at 06:11
  • 1
    The ajax call is asynchronous. Your `if(count_error == 0) {` code is executed before the ajax call finishes, so regardless of the outcome of the call, the `console.log("ok");` is executed. – Nick Jan 20 '21 at 06:13
  • @Nick, It does shed some light - but I'm not sure how any of that needs to be implemented within my code. There's an awful lot of info there, and I'm a bit n00b with AJAX. Thanks. – ctfd Jan 20 '21 at 06:14
  • Basically you either need to do all the processing in the ajax callback (preferred), or you need to wait for it to complete before checking the value of `count_error`. I know there's a lot of info in the answer, but you do need to understand it to be able to write this sort of code successfully so it's worth spending the time... – Nick Jan 20 '21 at 06:18
  • @Nick: I agree with you on that. My question basically comes down to what is the best approach to take based on the information in that answer? And is there a way to make AJAX do synchronous execution for this type of situation? I know I've seen "async" mentioned in the type of requests it makes, but don't know if that applies to things like this. – ctfd Jan 20 '21 at 06:22
  • @Nick: That answer is a wealth of information, thank you again. I don't know why it never came up in my search. I'm lost though on the best approach ... hmmm – ctfd Jan 20 '21 at 06:27
  • Just move the `if(count_error == 0)` inside your "success" callback so that it only executes after the response has been received – ADyson Jan 20 '21 at 08:02
  • @ADyson: Could you post an example? I'm still struggling with this AJAX... I'm thinking of burying my head in sand and giving up. – ctfd Jan 20 '21 at 08:57
  • Literally just move it. e.g. `success: function(response) { if ($.trim(response) == "success") { console.log("success"); } else { console.log("failed"); count_error++; } if(count_error == 0) { console.log("ok"); } }` . Not sure what you mean by "it still enters the next function" though...you don't have any other Javascript functions in your code. – ADyson Jan 20 '21 at 09:00
  • @ADyson: Well, the problem is that `if(count_error == 0)` is a statement that has a bunch of other functions in it. I wanted to use this code in my question as a sort of gatekeeper for those if that makes sense. – ctfd Jan 20 '21 at 09:05
  • That's fine. It's just that all of that needs to be fired from inside your success function. Basically, anything that relies on the result of the AJAX request needs to be executed inside (or at least triggered from) the "success" function of the AJAX. If you don't, then your code is the equivalent of someone trying to read a letter before the postman has delivered it. All modern web applications which use AJAX work in this way...you just need to get your head round the concept that your code isn't completely linear. Once you do, it opens up a whole world of possibilities. – ADyson Jan 20 '21 at 09:10
  • @ADyson: I did what you said, but I have a problem when I get the return response back. I'm returning a url like `https://example.com?q=string`. The problem is that when I go to `POST` it in the next ajax request it tries to post it as `https://example.com?q: string`. Not sure why it's losing the `=`... – ctfd Jan 20 '21 at 13:00
  • Neither am I, since you gave me no way to debug it. Sounds like a new problem though, so you should ask a new question about it, and then you can include relevant details. We need to see the code you're using to make the next AJAX request, we need to see output from your logs so we can see precisely where the value gets changed - e.g. is it intact when it arrives in the ping.php PHP? Is it intact when it arrives back into the JS in your console? Narrow down the problem so you can see (at least roughly) where the variable gets mutated. That way you know where to put your efforts into fixing. – ADyson Jan 20 '21 at 13:02
  • @ADyson: Yes, the string is returned fine from the PHP to the AJAX, it's when I try and send it with `data: returned_string` that mucks the string. Before it was sent as `data: $(this).serialize()` but it didn't work when I tried to do `data: returned_string.serialize()`. – ctfd Jan 20 '21 at 13:18
  • No, well, strings don't have a serialize() function - that's a function which jquery provides for form elements. And it wouldn't make sense if they did, either (if you understand what serialize() does then you'll get why). If you need to URL-encode the string (or part of it) then see https://stackoverflow.com/questions/332872/encode-url-in-javascript – ADyson Jan 20 '21 at 13:22

0 Answers0