javascript - 如何防止人们发送垃圾邮件 ajax 表单

标签 javascript php jquery ajax

我的问题是我有一个类似于 Stack Overflow 的投票系统。我的问题是,一个人可以向投票按钮发送垃圾邮件,这会导致投票按钮出现故障,并使其提交的次数超出预期。例如,如果某个帖子有 10 票赞成,我可以重复单击“赞成票”按钮,它会添加两到三票,而不是 1 票。同样,我可以使用“否决票”按钮来做到这一点。我该如何防止这种情况发生?

索引.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 vote() 函数

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

投票.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;
                }
            }
        }
    }
}

测试2.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.phpvote.php .

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

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

最佳答案

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

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

快速 JS hack:在提交时设置一个变量,在响应之前您不会清除该变量;如果设置了该变量,则无需提交表单。因此,垃圾邮件点击不会执行任何操作,因为第一次点击之后的每一次点击都将被忽略。

例如:

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/

相关文章:

php - PHP Table 下的背景图——方法

jquery - Bugzilla - 通过 JSON-RPC 的 Web 服务

javascript - react 表usePagination不应用分页

javascript - 在 React 中监听 Web 组件事件

php - 如何从表中选择所有行?

php - 验证类 - 应该返回 false 还是抛出异常?

javascript - 使用 jQuery 从一个函数传递到另一个函数的变量在 .post 之后变得未定义

javascript - 使用切换按钮将事件面板与事件模式同步

JavaScript - 是否可以修改第三方脚本(外部托管)使用的 setInterval/setTimeout 的行为

javascript - 根据另一个对象数组的顺序对对象数组进行排序