admin管理员组

文章数量:1428474

There are several questions like this on SO but none of the answers have worked for me. I have tried them all.

I tried to minimize the code I am pasting, but it's kind of hard with this script

I have a ment form that is submitted via ajax to a php script which saves the ment and then gets all the ments and redisplays them so the new ment can be displayed without refreshing the page.

Only sometimes will the ments successfully submit to the database and redisplay properly. Usually almost every other submit the ment will be saved. Every other time nothing seems to happen.

My real issue is the ments not being saved every time one is submitted.

Here is the javascript and the ajax call:

$(document).ready(function(){
    var working = false;

    $('#mentForm').submit(function(e){

        if(working) return false;

        working = true;
        $('#submitComment').val('Working..');
        $('span.error').remove();

        $.post('/ajax/ment.process.php',$(this).serialize(),function(msg){

            working = false;
            $('#submitComment').val('Submit');

            if(msg.status){

                $('#mentArea').slideDown().$(msg.html).prepend('#mentArea');
            $('#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 submits the ment:

public function addComment($user_id) {

    $validate = new data_validation;

    $_POST = $validate->sanitize($_POST);

    $newCom = $_POST['blogComment'];
    $blog_id = intval($_POST['blogID']);
    $photoSubmit = $_POST['Photo'];

    $newComQuery = $this->mysqli->query("INSERT INTO b_ments (blog_id, user_id, date, content, photo) VALUES ('".$blog_id."', '".$user_id."', Now(), '".$newCom."', '".$photoSubmit."')");

    if($newComQuery === false) {
        echo "Query failed";
    }else{

        $returnCom = $this->Markup($blog_id);
        echo $returnCom;

    }           
}

and here is a piece of the Markup() function that echos the ments (it is only the important pieces):

//  This method outputs the XHTML markup of the ment
public function Markup($blog_id) {

    $sql = $this->mysqli->query("SELECT * FROM b_ments WHERE blog_id = '".$blog_id."' ORDER BY date DESC");

    while($d = $sql->fetch_assoc()) {

        $d = $validate->sanitize($d);

        echo "

            <div class='ment-block'>
                <span class='-img'><img src='".$photo_path."' /></span>
                <h3 style='display: inline;'><a href='".$profile."'>".$userName."</a></h3>
                <div class='-date'>".$d['date']."</div>
                <p>".$Content."</p>
            </div>
        ";
    }
}

EDIT: Here is the ment.process.php code as requested:

    session_start();

include_once('../classes/ment.class.php');
include_once('../classes/db.class.php');
include_once('../classes/user.class.php');

$user_id = $_SESSION['user_id'];

$db = new DBConnection;
$ments = new Comment($db);
$user = new User($db);

$blogID = intval($_POST['blogID']);

$addCom = $ments->addComment($user_id);

echo json_encode(array('status'=>1,'html'=>$addCom));

There are several questions like this on SO but none of the answers have worked for me. I have tried them all.

I tried to minimize the code I am pasting, but it's kind of hard with this script

I have a ment form that is submitted via ajax to a php script which saves the ment and then gets all the ments and redisplays them so the new ment can be displayed without refreshing the page.

Only sometimes will the ments successfully submit to the database and redisplay properly. Usually almost every other submit the ment will be saved. Every other time nothing seems to happen.

My real issue is the ments not being saved every time one is submitted.

Here is the javascript and the ajax call:

$(document).ready(function(){
    var working = false;

    $('#mentForm').submit(function(e){

        if(working) return false;

        working = true;
        $('#submitComment').val('Working..');
        $('span.error').remove();

        $.post('/ajax/ment.process.php',$(this).serialize(),function(msg){

            working = false;
            $('#submitComment').val('Submit');

            if(msg.status){

                $('#mentArea').slideDown().$(msg.html).prepend('#mentArea');
            $('#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 submits the ment:

public function addComment($user_id) {

    $validate = new data_validation;

    $_POST = $validate->sanitize($_POST);

    $newCom = $_POST['blogComment'];
    $blog_id = intval($_POST['blogID']);
    $photoSubmit = $_POST['Photo'];

    $newComQuery = $this->mysqli->query("INSERT INTO b_ments (blog_id, user_id, date, content, photo) VALUES ('".$blog_id."', '".$user_id."', Now(), '".$newCom."', '".$photoSubmit."')");

    if($newComQuery === false) {
        echo "Query failed";
    }else{

        $returnCom = $this->Markup($blog_id);
        echo $returnCom;

    }           
}

and here is a piece of the Markup() function that echos the ments (it is only the important pieces):

//  This method outputs the XHTML markup of the ment
public function Markup($blog_id) {

    $sql = $this->mysqli->query("SELECT * FROM b_ments WHERE blog_id = '".$blog_id."' ORDER BY date DESC");

    while($d = $sql->fetch_assoc()) {

        $d = $validate->sanitize($d);

        echo "

            <div class='ment-block'>
                <span class='-img'><img src='".$photo_path."' /></span>
                <h3 style='display: inline;'><a href='".$profile."'>".$userName."</a></h3>
                <div class='-date'>".$d['date']."</div>
                <p>".$Content."</p>
            </div>
        ";
    }
}

EDIT: Here is the ment.process.php code as requested:

    session_start();

include_once('../classes/ment.class.php');
include_once('../classes/db.class.php');
include_once('../classes/user.class.php');

$user_id = $_SESSION['user_id'];

$db = new DBConnection;
$ments = new Comment($db);
$user = new User($db);

$blogID = intval($_POST['blogID']);

$addCom = $ments->addComment($user_id);

echo json_encode(array('status'=>1,'html'=>$addCom));
Share Improve this question edited Mar 15, 2013 at 20:28 Ty Bailey asked Mar 13, 2013 at 0:28 Ty BaileyTy Bailey 2,43211 gold badges48 silver badges79 bronze badges 11
  • It seems there is some problem with the variable 'working'. Are you sure it is implemented correctly? – GBRocks Commented Mar 13, 2013 at 3:49
  • I guess I'm not sure it is, however I removed it pletely and it still wasn't working. – Ty Bailey Commented Mar 13, 2013 at 4:14
  • where you used $('#blogComment').val()? – Amir Commented Mar 13, 2013 at 14:40
  • @Amir I don't understand what you are asking? – Ty Bailey Commented Mar 13, 2013 at 17:11
  • 4 When you open your browser's Developer Tools, are you seeing the ajax request being made when you click the submit button. If so is the web server returning 200, or some other error code like 500? Try to first figure out where the problem is. You could always eliminate js/ajax by creating some simple test page with a normal html form that submits to /ajax/ment.process.php – Adam Magaluk Commented Mar 21, 2013 at 13:51
 |  Show 6 more ments

9 Answers 9

Reset to default 1

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

But there are a few logic, efficiency, and manageability issues with the way you've drawn up the process. I'd remend having a look at the official jQuery docs for $.post(), specifically the .done(), .fail(), and .always() chained methods.

I'd also remend naming your PHP variable something other than $_POST, so it does not bee confused with the PHP super global.

Finally, I'd remend treating your ment as an object and using PDO (this is a link to PDO:query as a kind of "immersion" approach but be sure to read all the docs). It will save you a ton of headaches in database interaction.

It looks like you've got a race condition caused by the working flag. Since you're just using that flag to show the "working..." message and prevent submits while a request is processing, I would just use the normal $.ajax call and put the "working" logic in the beforeSend option. Here's an example:

$(document).ready(function(){
    $('#mentForm').submit(function(e){
        $.ajax({
            type: 'POST'
            url: '/ajax/ment.process.php',
            dataType: 'json',
            beforeSend: function(jqXHR, settings) {
                $('#submitComment').val('Working..');
                $('span.error').remove();
            },
            data: $(this).serialize(),
            plete: function(jqXHR, textStatus) {
                var msg = jqXHR.responseText;
                $('#submitComment').val('Submit');

                if(msg.status){
                    $('#mentArea').slideDown().$(msg.html).prepend('#mentArea');
                    $('#blogComment').val('');
                }
                else {
                    $.each(msg.errors,function(k,v){
                        $('label[for='+k+']').append('<span class="error">'+v+'</span>');
                    });
                }
            };
        });
    });
});

are you using json_encode()? if not all your echo-backs will be received as "text" and not as an json-object which you're accessing in your jquery

I guess you should use encodeURIComponent($('#blogComment').val()) somwhere for passing your blogment value to PHP file for insert.

Edit 1:

public function addComment($user_id) {

    $validate = new data_validation;

    $_POST = $validate->sanitize($_POST);

    $newCom = rawurlencode($_POST['blogComment']);

if rawurlencode() did not work. use following function:

function encodeURIComponentNew($str) {

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

(function from What is the equivalent of JavaScript's encodeURIponent in PHP?)

and then

public function addComment($user_id) {

    $validate = new data_validation;

    $_POST = $validate->sanitize($_POST);

    $newCom = encodeURIComponentNew($_POST['blogComment']);

Doubt this is related, but I've had issues in the past when doing ajax stuff using "echo" inside a function, and then trying to echo the returned value again.

Try changing your echo's inside all your functions for "return" instead like so:

public function addComment($user_id) {

    $validate = new data_validation;

    $_POST = $validate->sanitize($_POST);

    $newCom = $_POST['blogComment'];
    $blog_id = intval($_POST['blogID']);
    $photoSubmit = $_POST['Photo'];

    $newComQuery = $this->mysqli->query("INSERT INTO b_ments (blog_id, user_id, date, content, photo) VALUES ('".$blog_id."', '".$user_id."', Now(), '".$newCom."', '".$photoSubmit."')");

    if($newComQuery === false) {
        return "Query failed";
    }else{
        $returnCom = $this->Markup($blog_id);
        return $returnCom;
    }           
}

If the user send a ment with ' maybe will happens an error. When you send a ment, the string will broke a 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['Photo'], ENT_QUOTES);

$newComQuery = $this->mysqli->query("INSERT INTO b_ments (blog_id, user_id, date, content, photo) VALUES ('".$blog_id."', '".$user_id."', Now(), '".$newCom."', '".$photoSubmit."')");

if($newComQuery === false) {
    echo "Query failed";
}else{

    $returnCom = $this->Markup($blog_id);
    echo $returnCom;

}           

}

It might cause of Browser cookiess. So that In your URL just add addtional queryString for unique URL pattern.

Example:

   $.post('/ajax/ment.process.php?random=randamnumber');

You have a SQL Injection vulnerability in your PHP code, make sure you're escaping your variables properly or use a prepared query.

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

Also, your 'working' variable can be set forever to true if there's an error in your php script, which is very likely to happen with the SQL Injection Vuln in place.

Explanation: You set it to true, success callback possibly doesn't get called because of error 500 from PHP Backend, so it never gets set to false by your callback, and then you can't ever submit anymore till next page refresh.

So, if I understand the problem correctly, you're submitting the ment and it's not inserting into the database, and it's also presumably not showing you a database error or printing out your Query failed string?

It seems as though your PHP script isn't being executed at all?

If this is the case, I would normally say the most likely culprit for an intermittent error like this is your browser cache. Your browser is looking at the URL, thinks it already knows what content goes with that URL, and returns that content without ever even sending your info to the server. The simplest way to beat that is to add a random querystring to your file call, e.g.:

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

... I say "normally" since you're using POST and under "normal" circumstances the browser does not cache POST requests. But it is possible, and it's trivial to bat, so give it a shot. This can also be diagnosed, if you use Chrome, by hitting f12, going to the "network" tab, and then running your form. It should tell you if the result was retrieved from cache.

Beyond that, if you're relying on magic_quotes (or worse, you're not relying on magic_quotes), you need to learn the proper way to deal with SQL injection. You should never be inserting untrusted data from the browser directly into the database. Escape it or use parameterized queries. If you're experiencing an intermittent problem with your query, it's probably related to the content of your ment throwing the query off under certain circumstances, as mentioned above, most likely with the inclusion of an apostrophe in a contraction. Diagnose by submitting two forms back to back: trythis and then try'this. If the first one goes and the second one fails, you've likely found your answer. Properly escaping your input would solve this problem.

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


Edit: I see, now that I look closer, that you are in fact escaping your query with a method you haven't shared here. Assuming that's working correctly, then that shouldn't be a concern.

Try echoing out a valid response at the beginning of your script without even executing anything. If that always returns, then you at least know the script is being called successfully.

There could be a problem with your working variable in the event that the ajax call returns with an error. It would never, under those circumstances, set it back to false.

Your #1 ally is the "network" tab in Chrome Developer Tools or watching the response in the console tab in Firefox Firebug extension.


Edit 2:

$.post('/ajax/ment.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; });

本文标签: phpAjax form only submitting sometimesStack Overflow