Ajax form only presents sometimes

There are several such questions on SO, but none of the answers worked for me. I tried them all.

I tried to minimize the code I embed, but the script is hard to handle

I have a comment form that is passed via ajax to a php script that saves the comment and then receives all the comments and re-displays them so that the new comment can be displayed without refreshing the page.

Only sometimes comments will be successfully sent to the database and displayed correctly. Usually almost every other post sends a comment will be saved. Nothing else seems to be happening.

My real problem is that comments are not saved on every submission.

Here is the javascript and ajax call:

$(document).ready(function(){ var working = false; $('#commentForm').submit(function(e){ if(working) return false; working = true; $('#submitComment').val('Working..'); $('span.error').remove(); $.post('/ajax/comment.process.php',$(this).serialize(),function(msg){ working = false; $('#submitComment').val('Submit'); if(msg.status){ $('#commentArea').slideDown().$(msg.html).prepend('#commentArea'); $('#blogComment').val(''); } else { $.each(msg.errors,function(k,v){ $('label[for='+k+']').append('<span class="error">'+v+'</span>'); }); } },'json'); }); }); 

and here is the function that sends the comment:

 public function addComment($user_id) { $validate = new data_validation; $_POST = $validate->sanitize($_POST); $newCom = $_POST['blogComment']; $blog_id = intval($_POST['blogID']); $photoSubmit = $_POST['comPhoto']; $newComQuery = $this->mysqli->query("INSERT INTO b_comments (blog_id, user_id, date, content, photo) VALUES ('".$blog_id."', '".$user_id."', Now(), '".$newCom."', '".$photoSubmit."')"); if($newComQuery === false) { echo "Query failed"; }else{ $returnCom = $this->comMarkup($blog_id); echo $returnCom; } } 

and here is a fragment of the comMarkup() function, which selects comments (these are only important fragments):

 // This method outputs the XHTML markup of the comment public function comMarkup($blog_id) { $sql = $this->mysqli->query("SELECT * FROM b_comments WHERE blog_id = '".$blog_id."' ORDER BY date DESC"); while($d = $sql->fetch_assoc()) { $d = $validate->sanitize($d); echo " <div class='comment-block'> <span class='com-img'><img src='".$photo_path."' /></span> <h3 style='display: inline;'><a href='".$profile."'>".$userName."</a></h3> <div class='com-date'>".$d['date']."</div> <p>".$comContent."</p> </div> "; } } 

EDIT: Here is the comment.process.php code for the query:

  session_start(); include_once('../classes/comment.class.php'); include_once('../classes/db.class.php'); include_once('../classes/user.class.php'); $user_id = $_SESSION['user_id']; $db = new DBConnection; $comments = new Comment($db); $user = new User($db); $blogID = intval($_POST['blogID']); $addCom = $comments->addComment($user_id); echo json_encode(array('status'=>1,'html'=>$addCom)); 
+4
source share
9 answers

Given your description, I assume that it has something to do with your working variable and that it is not set to false at the end of your $.post() .

But there are a few problems with logic, efficiency, and manageability with how you compiled this process. I would recommend looking at jQuery's official docs for $ .post () , specifically .done() , .fail() and .always() chain methods.

I would also recommend calling your PHP variable something other than $_POST , so it doesn't get confused with super-global PHP.

Finally, I would recommend treating your comment as an object and using PDO (this is a reference to PDO: query as a kind of "dive", but be sure to read all the documents). This will save a lot of headaches when interacting with the database.

+1
source

It looks like you have a race condition caused by the working icon. Since you just use this flag to display the message "working ..." and prevent sending during processing the request, I would just use the usual call to $.ajax and put the "working" logic in the beforeSend option. Here is an example:

 $(document).ready(function(){ $('#commentForm').submit(function(e){ $.ajax({ type: 'POST' url: '/ajax/comment.process.php', dataType: 'json', beforeSend: function(jqXHR, settings) { $('#submitComment').val('Working..'); $('span.error').remove(); }, data: $(this).serialize(), complete: function(jqXHR, textStatus) { var msg = jqXHR.responseText; $('#submitComment').val('Submit'); if(msg.status){ $('#commentArea').slideDown().$(msg.html).prepend('#commentArea'); $('#blogComment').val(''); } else { $.each(msg.errors,function(k,v){ $('label[for='+k+']').append('<span class="error">'+v+'</span>'); }); } }; }); }); }); 
+1
source

Are you using json_encode ()? if not all of your echoes will be accepted as "text" and not as the json object you are accessing in your jquery

0
source

I assume that you should use encodeURIComponent($('#blogComment').val()) somwhere to pass your blogcomment value to the PHP file for insertion.

Change 1:

 public function addComment($user_id) { $validate = new data_validation; $_POST = $validate->sanitize($_POST); $newCom = rawurlencode($_POST['blogComment']); 

if rawurlencode() not working. use the following function:

 function encodeURIComponentNew($str) { $revert = array('%21'=>'!', '%2A'=>'*', '%27'=>"'", '%28'=>'(', '%29'=>')'); return strtr(rawurlencode($str), $revert); } 

(function from What is the equivalent encodingURI JavaScript code in PHP? )

and then

 public function addComment($user_id) { $validate = new data_validation; $_POST = $validate->sanitize($_POST); $newCom = encodeURIComponentNew($_POST['blogComment']); 
0
source

I doubt this is related, but I had problems in the past when I was doing ajax material using the "echo" inside the function, and then trying again to repeat the return value.

Try changing the echo in all your functions to "return", and not like this:

 public function addComment($user_id) { $validate = new data_validation; $_POST = $validate->sanitize($_POST); $newCom = $_POST['blogComment']; $blog_id = intval($_POST['blogID']); $photoSubmit = $_POST['comPhoto']; $newComQuery = $this->mysqli->query("INSERT INTO b_comments (blog_id, user_id, date, content, photo) VALUES ('".$blog_id."', '".$user_id."', Now(), '".$newCom."', '".$photoSubmit."')"); if($newComQuery === false) { return "Query failed"; }else{ $returnCom = $this->comMarkup($blog_id); return $returnCom; } } 
0
source

If the user submits a comment using ' , an error may occur. When you post a comment, the line will be split into mmysqli_query. It can help you, MAYBE.

public function addComment ($ user_id) {

 $validate = new data_validation; $_POST = $validate->sanitize($_POST); $newCom = htmlspecialchars($_POST['blogComment'], ENT_QUOTES); $blog_id = intval($_POST['blogID']); $photoSubmit = htmlspecialchars($_POST['comPhoto'], ENT_QUOTES); $newComQuery = $this->mysqli->query("INSERT INTO b_comments (blog_id, user_id, date, content, photo) VALUES ('".$blog_id."', '".$user_id."', Now(), '".$newCom."', '".$photoSubmit."')"); if($newComQuery === false) { echo "Query failed"; }else{ $returnCom = $this->comMarkup($blog_id); echo $returnCom; } 

}

0
source

This could lead to a browser cookie . So in the URL just add addStional queryString for the unique URL pattern.

Example:

  $.post('/ajax/comment.process.php?random=randamnumber'); 
0
source

So, if I understand the problem correctly, do you post a comment and do not paste into the database, and also presumably do not show the database error or print the Query failed line?

Does your PHP script seem to not run at all?

If so, I would say most likely the culprit of an intermittent error, such as your browser cache. Your browser looks at the URL, thinks it already knows what content comes with that URL, and returns that content without even sending information to the server. The easiest way to hack this is to add a random request to your file call, for example:

 cachebuster = new Date(); '/ajax/comment.process.php?cachebuster='.cachebuster.getTime(); 

... I say "normal" since you are using POST and in "normal" circumstances the browser does not cache POST requests. But it’s possible, and it’s trivial to fight, so give him a chance. This can also be diagnosed if you use Chrome by pressing f12, go to the "network" tab, and then run your form. He should tell you if the result was obtained from the cache.

In addition, if you rely on magic_quotes (or, even worse, you do not rely on magic_quotes), you need to learn the right way to deal with SQL injection. You should never embed untrusted data from a browser directly into a database. Exit it or use parameterized queries. If you have a periodic problem with your request, it is probably related to the content of your comment, discarding the request under certain circumstances, as mentioned above, most likely, including the apostrophe in compression. Diagnose by sending two forms back: trythis , and then try'this . If the first goes, and the second fails, you most likely found your answer. Proper avoidance of input will help solve this problem.

Ultimately, all of these suggestions have already been given above, but hopefully this provides a little context to help understand why and where.


Edit: now I see that you are actually avoiding your request with a method that you have not used here. Assuming the job is correct, then this should not be a problem.

Try to repeat the valid answer at the beginning of your script without even executing anything. If this always returns, you at least know that the script call is successful.

There may be a problem with your working variable in case the ajax call is returned with an error. In such circumstances, it will never return false.

Your # 1 ally is the “Network” tab in Chrome’s Developer Tools or viewing the response on the console tab in the Firefox Firebug extension.


Edit 2:

 $.post('/ajax/comment.process.php',$(this).serialize(),function(msg){ // post stuff, REMOVING the working variable set, cuz it won't be necessary here... },'json').always(function() { working = false; }); 
0
source

If you have a SQL Injection vulnerability in your PHP code, make sure that you are properly escaping your variables or using a prepared query.

As for the JS part, be sure to return true; at the end of your .submit () function. (for you, it will be after calling $ .post ())

In addition, your “working” variable can be set to true forever if an error occurred in your php script, which very likely happened with SQL Injection Vuln in place.

The explanation . You set to true, a successful callback may not have been called due to a 500 error from PHP Backend, so it never gets false when called back, and then you can never send it again until the next page is refreshed.

0
source

Source: https://habr.com/ru/post/1468862/


All Articles