Ajax表单有时只提交

时间:2013-03-13 00:28:49

标签: php javascript jquery mysql ajax

在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));

9 个答案:

答案 0 :(得分:1)

根据您的说明,我的猜测是,它与您的working变量有关,而且它在false的末尾没有设置为$.post()

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

我还建议将PHP变量命名为$_POST之外的其他内容,这样就不会与PHP超级全局混淆。

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

答案 1 :(得分:1)

看起来你有working标志引起的竞争条件。由于您只是使用该标志来显示“正在工作...”消息并在请求处理时阻止提交,我将使用正常的$.ajax调用并将“工作”逻辑放在{{ 1}}选项。这是一个例子:

beforeSend

答案 2 :(得分:0)

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

答案 3 :(得分: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']);

答案 4 :(得分:0)

怀疑这是相关的,但是在过去使用函数内部使用“echo”执行ajax的东西,然后尝试再次回显返回的值时,我遇到了一些问题。

尝试在“返回”中更改所有函数内部的echo,如下所示:

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

答案 5 :(得分: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;

}           

}

答案 6 :(得分:0)

可能会导致浏览器Cookie 。因此,在网址中,只需为唯一网址格式添加其他查询字符串。

示例:

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

答案 7 :(得分:0)

因此,如果我正确理解了问题,您就会提交评论并且没有插入数据库,并且它的可能不会向您展示数据库错误或打印出Query failed字符串?

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

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

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

...我说&#34;通常&#34;因为你正在使用POST并且正常&#34;正常&#34;情况下,浏览器不会缓存POST请求。但这是可能的,并且打击是微不足道的,所以试一试。这也可以诊断,如果你使用Chrome,点击f12,进入&#34;网络&#34;选项卡,然后运行您的表单。它应告诉您是否从缓存中检索到结果。

除此之外,如果你依赖magic_quotes(或者更糟糕的是,你 依赖magic_quotes),你需要学习处理SQL注入的正确方法。您永远不应该将不受信任的数据从浏览器直接插入数据库。转义它或使用参数化查询。如果您的查询出现间歇性问题,则可能与您在某些情况下抛弃查询的评论内容有关,如上所述,最有可能是收缩中包含撇号。通过连续提交两个表单进行诊断:trythis然后try'this。如果第一个失败了,第二个失败了,你很可能找到了答案。正确地逃避你的输入将解决这个问题。

最终,所有这些建议都已在上面给出,但希望这提供了一些背景来帮助理解为什么和为什么会这样做。


编辑:我知道,现在我看起来更接近了,你实际上是用你在这里分享的方法来逃避你的查询。假设它正常工作,那么就不应该成为一个问题。

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

如果ajax调用返回错误,可能成为working变量的问题。在这种情况下,它永远不会让它回归假。

你的#1盟友是&#34;网络&#34; 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; });

答案 8 :(得分:0)

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

对于JS部分,请确保返回true;在.submit()函数的末尾。 (对你而言,它将在$ .post()调用之后)

此外,如果您的php脚本中存在错误,那么您的'working'变量可以永久设置为true,这对于SQL Injection Vuln来说非常可能

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