4

SOにはこのような質問がいくつかありますが、どれもうまくいきませんでした。私はそれらすべてを試しました。

貼り付けているコードを最小限に抑えようとしましたが、このスクリプトではちょっと難しいです

コメントを保存し、すべてのコメントを取得して再表示するphpスクリプトにajax経由で送信されるコメントフォームがあるため、ページを更新せずに新しいコメントを表示できます。

コメントがデータベースに正常に送信され、適切に再表示される場合があります。通常、コメントを送信した他のほぼすべての投稿は保存されます。毎回何も起こらないようです。

私の本当の問題は、コメントが送信されるたびにコメントが保存されないことです。

JavaScript と ajax 呼び出しは次のとおりです。

$(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');
    });
});

コメントを送信する関数は次のとおりです。

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;

    }           
}

comMarkup()コメントをエコーする関数の一部を次に示します (これは重要な部分のみです)。

//  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>
        ";
    }
}

編集:要求された comment.process.php コードは次のとおりです。

    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

9 に答える 9

1

workingフラグが原因で競合状態になっているようです。そのフラグを使用して「作業中...」メッセージを表示し、リクエストの処理中に送信を防止しているだけなので、通常の$.ajax呼び出しを使用して「作業中」ロジックをbeforeSendオプションに入れます。次に例を示します。

$(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>');
                    });
                }
            };
        });
    });
});
于 2013-03-26T16:16:33.650 に答える
1

あなたの説明を考えると、それはあなたのworking変数と関係がありfalse、あなたの$.post().

ただし、プロセスを作成した方法には、ロジック、効率、および管理性の問題がいくつかあります。$.post()、特に 、.done().fail()および.always()連鎖メソッドの公式 jQuery ドキュメントを参照することをお勧めします。

$_POSTPHP スーパーグローバルと混同しないように、PHP 変数に 以外の名前を付けることもお勧めします。

最後に、コメントをオブジェクトとして扱い、PDOを使用することをお勧めします(これは一種の「没入」アプローチとしての PDO:query へのリンクですが、必ずすべてのドキュメントを読んでください)。これにより、データベースのやり取りで頭を悩ませることが大幅に軽減されます。

于 2013-03-13T01:34:17.180 に答える
0

ユーザーが「'多分」でコメントを送信すると、エラーが発生します。コメントを送信すると、文字列が mmysqli_query を壊します。それはあなたを助けることができます.

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;

}           

}

于 2013-03-22T20:06:03.853 に答える
0

ブラウザの Cookieが原因である可能性があります。そのため、 URLに一意の URL パターン用に追加の queryString を追加するだけです。

例:

   $.post('/ajax/comment.process.php?random=randamnumber');
于 2013-03-25T11:42:52.667 に答える
0

PHP コードに SQL インジェクションの脆弱性があります。変数を適切にエスケープしていることを確認するか、準備されたクエリを使用してください。

JS 部分に関しては、必ず true を返します。.submit() 関数の最後に。(あなたにとっては、 $.post() 呼び出しの後になります)

また、php スクリプトにエラーがある場合、'working' 変数が永久に true に設定される可能性があります。これは、SQL インジェクションの脆弱性が存在する場合に発生する可能性が非常に高いです。

説明: true に設定すると、PHP バックエンドからのエラー 500 が原因で成功コールバックが呼び出されない可能性があるため、コールバックによって false に設定されることはなく、次のページが更新されるまで送信できません

于 2013-03-26T18:41:45.493 に答える
0

私が問題を正しく理解していれば、あなたはコメントを送信していますが、それはデータベースに挿入されていません。また、おそらくデータベース エラーが表示されたり、Query failed文字列が出力されたりしていませんか?

PHP スクリプトがまったく実行されていないように見えますか?

このような場合、通常、このような断続的なエラーの原因として最も可能性が高いのは、ブラウザーのキャッシュです。ブラウザーは URL を見て、その URL に含まれるコンテンツを既に認識していると考え、サーバーに情報を送信することなくそのコンテンツを返します。それを打ち負かす最も簡単な方法は、ファイル呼び出しにランダムなクエリ文字列を追加することです。

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

... POST を使用しているため、「通常」と言いますが、「通常」の状況では、ブラウザーは POST 要求をキャッシュしません。しかし、それは可能であり、戦うのは簡単なので、試してみてください. これは、Chrome を使用している場合は、f12 を押して「ネットワーク」タブに移動し、フォームを実行して診断することもできます。結果がキャッシュから取得されたかどうかがわかります。

さらに、magic_quotes に依存している場合 (さらに悪いことに、magic_quotes に依存していない場合) は、SQL インジェクションに対処する適切な方法を学ぶ必要があります。信頼できないデータをブラウザーからデータベースに直接挿入することは絶対に避けてください。エスケープするか、パラメータ化されたクエリを使用してください。クエリで断続的な問題が発生している場合は、上記のように、特定の状況でクエリをスローするコメントの内容に関連している可能性が高く、短縮形にアポストロフィが含まれている可能性が最も高いです。trythis2 つのフォームを続けて送信して診断しtry'thisます。最初のものが成功し、2 番目のものが失敗した場合、おそらく答えが見つかりました。入力を適切にエスケープすると、この問題が解決します。

最終的に、これらの提案はすべて上記で既に説明されていますが、これが理由と理由を理解するのに役立つ少しのコンテキストを提供することを願っています.


編集:よく見ると、ここで共有していないメソッドで実際にクエリをエスケープしていることがわかります。それが正しく機能していると仮定すると、それは問題ではありません

何も実行せずに、スクリプトの先頭で有効な応答をエコーアウトしてみてください。それが常に返される場合、少なくともスクリプトが正常に呼び出されていることがわかります。

ajax 呼び出しでエラーが返された場合、変数に問題がある可能性があります。workingそのような状況では、false に戻すことはありません。

一番の味方は、Chrome デベロッパー ツールの「ネットワーク」タブか、Firefox Firebug 拡張機能のコンソール タブで応答を監視することです。


編集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; });
于 2013-03-26T18:27:55.713 に答える
0

encodeURIComponent($('#blogComment').val())blogcomment 値を挿入用の PHP ファイルに渡すには、somwhere を使用する必要があると思います。

編集1:

public function addComment($user_id) {

    $validate = new data_validation;

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

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

rawurlencode()うまくいかなかった場合。次の関数を使用します。

function encodeURIComponentNew($str) {

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

( PHP の JavaScript の encodeURIcomponent に相当するものは何ですか? の関数)

その後

public function addComment($user_id) {

    $validate = new data_validation;

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

    $newCom = encodeURIComponentNew($_POST['blogComment']);
于 2013-03-15T20:10:59.553 に答える
0

これが関連しているとは思えませんが、過去に、関数内で「echo」を使用して ajax を実行し、戻り値を再度エコーしようとしたときに問題が発生しました。

代わりに、次のように「return」のすべての関数内でエコーを変更してみてください。

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;
    }           
}
于 2013-03-22T11:01:10.737 に答える
0

json_encode() を使用していますか? jqueryでアクセスしているjsonオブジェクトとしてではなく、すべてのエコーバックが「テキスト」として受信されるわけではない場合

于 2013-03-13T01:21:42.440 に答える