Closed. This question needs details or clarity。它当前不接受答案。
                        
                    
                
            
        
            
        
                
                    
                
            
                
                    想改善这个问题吗?添加详细信息并通过editing this post阐明问题。
                
                    6年前关闭。
            
        

    

我的问题是我有一个类似于Stack Overflow的投票系统。我的问题是,一个人可以发送“投票”按钮作为垃圾邮件,这会使它出现故障并使其提交的次数超出了预期。例如,如果某条帖子有10票赞成票,我可以反复单击“票赞成票”按钮,它会添加2或3票赞成票,而不是1票。同样,我可以使用“否决”按钮来完成此操作。我该如何预防?

Index.php:

<?php
session_start();
require('db.php');
$pid = 2;
$uid = $_SESSION['id'];
$sql = mysqli_query($con, "SELECT * FROM posts WHERE pid = '$pid'"); //check to see how many likes the post has
$r = mysqli_fetch_assoc($sql);
$body = $r['body'];
$likes = $r['likes'];
$sql2 = mysqli_query($con, "SELECT * FROM likes WHERE pid = '$pid' AND uid = '$uid'");      //check to see if user has voted
$n = mysqli_num_rows($sql2);
if ($n == 0) {
    //user hasn't liked or down vote anything yet
    $liked = "no";
} else {
    if ($n > 1) {
        //like scammed
        echo "<script>alert('Stop spamming for votes. You are banned for spam.')</script>";
        exit("You have been banned for spam");
        //This isn't fool proof though, and I don't want to ban people for this. It would be best if I could just prevent the vote scam in the first place
    }
$r = mysqli_fetch_assoc($sql2);
$type = $r['like_type'];
if ($type == '0') {
    $liked = "liked";
} else {
    $liked = "disliked";
}
}
?>
<!DOCTYPE html>
<html>
<head>
    <title>Test</title>
    <script src="//code.jquery.com/jquery-latest.min.js"></script>
    <style>
        .selected {
            color: red;
        }
    </style>
</head>
<body>
<div class="post">
    <p><?php echo $body; ?></p>
</div>
<div class="likes">
    <a href="javascript:;" class="upvote <?php if ($liked == 'liked') {echo "selected";} ?>" id='up-<?php echo $pid; ?>' onclick="vote('up', '<?php echo $pid; ?>', '<?php echo $uid; ?>', 'up-<?php echo $pid; ?>', 'votes-<?php echo $pid; ?>')">Upvote</a>
    <span id="votes-<?php echo $pid; ?>"><?php echo $likes; ?></span>
    <a href="javascript:;" class="downvote <?php if ($liked == 'disliked') {echo "selected";} ?>" id='down-<?php echo $pid; ?>' onclick="vote('down', '<?php echo $pid; ?>', '<?php echo $uid; ?>', 'down-<?php echo $pid; ?>', 'votes-<?php echo $pid; ?>')">Downvote</a>
</div>
</body>


JavaScript的表决()函数

function vote(type, pid, uid, id, voteId) {
var vote = $('#'+ id);
if (vote.hasClass('selected')) {
    //user voted for this
    $.post("vote.php", {pid: pid, uid: uid, type: type, vote: 'reset'}, function(d) {
        if (d == '0' || d == '1') {
            vote.removeClass('selected');
            var votes = $('#' + voteId);
            var num = votes.text();
            if (d == '1') {
                votes.text(++num);
            } else {
                votes.text(--num);
            }
        } else {
            alert('An error occurred')
        }
    });
} else {
    var upVoteId = $('#up-' + pid);
    var downVoteId = $('#down-' + pid);
    if (upVoteId.hasClass('selected') || downVoteId.hasClass('selected')) {
        //user wants to switch votes
        $.post('vote.php', {pid: pid, uid: uid, type: type, vote: 'switch'}, function(data) {
            var votes = $('#' + voteId);
            var num = votes.text();
            if (data == '1') {
                //downvote successful
                votes.text(parseInt(num) - 2);
                vote.addClass('selected');
                upVoteId.removeClass('selected');
            }
            if (data == '0') {
                //upvote successful
                votes.text(parseInt(num) + 2);
                vote.addClass('selected');
                downVoteId.removeClass('selected');
            }
            if (d == 'error') {
                alert('error');
            }
        });
    } else {
        $.post('test2.php', {type: type, pid: pid, uid: uid}, function(d) {
            if (d == "1") {
                //everything good
                $('#' + type + '-<?php echo $pid; ?>').addClass('selected');
                var votes = $("#" + voteId).text();
                if (type == 'down') {
                    //downvote
                    votes = --votes;
                    $('#' + voteId).text(votes);
                } else {
                    votes = ++votes;
                    $('#' + voteId).text(votes);
                }
            } else {
                alert('failed');
            }
        });
    }
}
}
}


Vote.php

<?php
session_start();
require('db.php');

if (!isset($_SESSION['id'], $_SESSION['un'])) {
    //not logged in
    header('Location: index.php');
    exit;
} else {
    if (!isset($_POST['uid'], $_POST['pid'], $_POST['type'], $_POST['vote'])) {
        //form not submitted
        header('Location: home.php');
        exit;
    } else {
        $uid = (int)$_SESSION['id'];
        $pid = (int)$_POST['pid'];
        $type = preg_replace('#[^a-z]#', '', $_POST['type']);
        $vote = preg_replace('#[^a-z]#', '',$_POST['vote']); //vote type

        if ($vote == 'reset') {
            //initiate vote reset
            if ($type == 'down') {
                //downvote
                $sql = mysqli_query($con, "DELETE FROM likes WHERE like_type = '1' AND pid = '$pid' AND uid = '$uid'"); //delete the downvote
                $sql2 = mysqli_query($con, "UPDATE posts SET likes = likes + 1 WHERE pid = '$pid'");
                if ($sql) {
                    echo "1"; // 1
                    exit;
                } else {
                    echo "error";
                    exit;
                }
            } else {
                //upvote
                $sql = mysqli_query($con, "DELETE FROM likes WHERE like_type = '0' AND pid = '$pid' AND uid = '$uid'"); //delete upvote
                $sql2 = mysqli_query($con, "UPDATE posts SET likes = likes - 1 WHERE pid = '$pid'");
                if ($sql) {
                    echo "0"; // 0
                    exit;
                } else {
                    echo "error";
                    exit;
                }
            }
        }

        if ($vote == 'switch') {
            //user wanted to switch vote
            if ($type == 'down') {
                //user had voted up but wants to vote down now
                $sql = mysqli_query($con, "DELETE FROM likes WHERE like_type = '0' AND pid = '$pid' AND uid = '$uid'"); //delete the previous vote
                $sql2 = mysqli_query($con, "INSERT INTO likes (pid, uid, like_type, date_liked) VALUES ('$pid', '$uid', '1', now())"); //insert new vote
                $sql3 = mysqli_query($con, "UPDATE posts SET likes = likes - 2 WHERE pid = '$pid'");
                if ($sql AND $sql2 AND $sql3) {
                    //all three queries were successful
                    echo "1";
                    exit;
                } else {
                    echo "error";
                    exit;
                }
            } else {
                //user had voted down but wants to vote up now
                $sql = mysqli_query($con, "DELETE FROM likes WHERE like_type = '1' AND pid = '$pid' AND uid = '$uid'") or die(mysqli_error($con)); //delete the previous vote
                $sql2 = mysqli_query($con, "INSERT INTO likes (pid, uid, like_type, date_liked) VALUES ('$pid', '$uid', '0', now())"); //insert new vote
                $sql3 = mysqli_query($con, "UPDATE posts SET likes = likes + 2 WHERE pid = '$pid'");
                if ($sql AND $sql2 AND $sql3) {
                    //all three queries were successful
                    echo "0";
                    exit;
                } else {
                    echo "error";
                    exit;
                }
            }
        }
    }
}


Test2.php

<?php
require('db.php');

$pid = $_POST['pid'];
$uid = $_POST['uid'];
$type = $_POST['type'];

if ($type == "down") {
    //downvote
    $type = 1;
    $sql = mysqli_query($con, "INSERT INTO likes (uid, pid, like_type, date_liked) VALUES ('$uid', '$pid', '$type', now())");
    $sql2 = mysqli_query($con, "UPDATE posts SET likes = likes - 1 WHERE pid = '$pid'");
    if ($sql) {
        echo '1';
        exit;
    }
} else {
    //upvote
    $type = 0;
    $sql = mysqli_query($con, "INSERT INTO likes (uid, pid, like_type, date_liked) VALUES ('$uid', '$pid', '$type', now())");
    $sql2 = mysqli_query($con, "UPDATE posts SET likes = likes + 1 WHERE pid = '$pid'");
    if ($sql) {
        echo '1';
        exit;
    }
}


这些是我当前使用的页面。我打算将移到test2.php

在我的数据库中,我有两个表,一个表用于存储所有帖子详细信息,包括票数。第二张表是存储谁投票支持哪个职位以及该职位是赞成票还是反对票。

如果我可以使我的系统更高效,请给我一些提示或建议。

最佳答案

快速的SQL破解:在pid,uid上创建唯一索引,以便用户只能对帖子投票一次。

例如:ALTER TABLE vote ADD UNIQUE INDEX pid_uid (pid, uid);

快速的JS hack:在Submit上设置一个变量,直到响应后您才清除它;如果设置了变量,则不提交表单。因此,点击垃圾邮件将无济于事,因为第一次点击之后的每次点击都将被忽略。

例如:

var submitting = false;
function submit_form()
{
    if (!submitting)
    {
        submitting = true;

        // example; insert actual arguments for it to work
        $.post(
            url,
            postData,
            function (data, textStatus)
            {
                submitting = false;
                // handle data here
            },
            "json"
        );
    }
}

关于javascript - 如何防止人们向Ajax表单发送垃圾邮件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23748271/

10-12 07:24