4

SO上有几个这样的问题,但没有一个答案对我有用。我都试过了。

我试图最小化我粘贴的代码,但是这个脚本有点难

我有一个评论表单,它通过 ajax 提交到一个 php 脚本,该脚本保存评论,然后获取所有评论并重新显示它们,以便在不刷新页面的情况下显示新评论。

只有有时评论才能成功提交到数据库并正确重新显示。通常几乎所有其他提交的评论都会被保存。每隔一段时间似乎什么都没有发生。

我真正的问题是每次提交评论时都没有保存评论。

这是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变量有关,并且它未设置为false您的$.post().

但是,您制定流程的方式存在一些逻辑、效率和可管理性问题。我建议查看$.post() 的官方 jQuery 文档,特别是.done(),.fail().always()链式方法。

我还建议您将 PHP 变量命名为 以外的名称$_POST,这样它就不会与 PHP 超级全局变量混淆。

最后,我建议将您的评论视为一个对象并使用PDO(这是指向 PDO:query 的链接,作为一种“沉浸式”方法,但请务必阅读所有文档)。它将为您节省大量数据库交互方面的麻烦。

于 2013-03-13T01:34:17.180 回答
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 回答
0

如果用户发送评论'可能会发生错误。当您发送评论时,该字符串将破坏 mmysqli_query。它可以帮助你,也许。

公共函数 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

所以,如果我正确理解了这个问题,你提交的评论并没有插入数据库,它可能没有显示数据库错误或打印出你的Query failed字符串?

好像您的 PHP 脚本根本没有被执行?

如果是这种情况,我通常会说像这样的间歇性错误最可能的罪魁祸首是您的浏览器缓存。您的浏览器正在查看 URL,认为它已经知道该 URL 附带的内容,并返回该内容,甚至无需将您的信息发送到服务器。最简单的方法是在文件调用中添加一个随机查询字符串,例如:

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

...我说“通常”,因为您使用的是 POST 并且在“正常”情况下,浏览器不会缓存 POST 请求。但这是可能的,而且战斗起来很简单,所以试一试。如果您使用 Chrome,也可以通过按 f12 键,转到“网络”选项卡,然后运行您的表单来诊断这种情况。它应该告诉您结果是否是从缓存中检索到的。

除此之外,如果您依赖于magic_quotes(或者更糟的是,您依赖于magic_quotes),您需要学习处理SQL 注入的正确方法。您永远不应该将来自浏览器的不受信任的数据直接插入数据库。转义它或使用参数化查询。如果您的查询遇到间歇性问题,这可能与您的评论内容有关,在某些情况下会引发查询,如上所述,很可能是在缩略词中包含撇号。通过背靠背提交两个表格进行诊断:trythis然后try'this。如果第一个成功而第二个失败,您可能已经找到了答案。正确转义您的输入将解决此问题。

最终,上面已经给出了所有这些建议,但希望这提供了一些背景信息来帮助理解原因和原因。


编辑:我看到,现在我仔细观察,您实际上是在使用您未在此处共享的方法转义您的查询。假设它工作正常,那么这不应该是一个问题。

尝试在脚本开头回显有效响应,甚至不执行任何操作。如果总是返回,那么您至少知道脚本被成功调用。

如果ajax 调用返回错误,您的变量可能会出现问题。working在这种情况下,它永远不会将其设置回 false。

您的 #1 盟友是 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())somwhere 将您的 blogcomment 值传递给 PHP 文件以进行插入。

编辑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);
}

(函数来自What is the equivalent of JavaScript's encodeURIcomponent in PHP?

接着

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 时遇到问题,然后尝试再次回显返回的值。

尝试将所有函数中的回声更改为“返回”,而不是像这样:

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

这可能是浏览器 cookie的原因。因此,在您的URL中,只需为唯一的 URL 模式添加额外的 queryString。

例子:

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

你在使用 json_encode() 吗?如果不是所有的回声都将作为“文本”而不​​是作为您在 jquery 中访问的 json 对象接收

于 2013-03-13T01:21:42.440 回答
0

您的 PHP 代码中存在 SQL 注入漏洞,请确保正确转义变量或使用准备好的查询。

至于JS部分,一定要返回true;在 .submit() 函数的末尾。(对你来说,它会在 $.post() 调用之后)

此外,如果您的 php 脚本中存在错误,您的“工作”变量可以永远设置为 true,这很可能发生在 SQL 注入漏洞到位的情况下。

说明您将其设置为 true,由于来自 PHP 后端的错误 500,可能不会调用成功回调,因此您的回调永远不会将其设置为 false,然后您将无法再提交,直到下一页刷新

于 2013-03-26T18:41:45.493 回答