将GET转换为POST以避免机器人搞乱投票

时间:2011-01-10 14:37:55

标签: php html post get robots.txt

我正在运行一个使用qdbs 1.10的网站,以提供基于PHP的报价数据库。投票通过GET实施,导致机器人不小心对报价进行投票。为避免这种情况,我想将GET请求转换为POST。

我是PHP的完全新手,也是一般的网络开发。是否有可能以最少的知识来执行这个机会?是否有任何模式可以遵循,或者您有一些关于如何做的提示?

(我正在将robots.txt更改为临时解决方案,但这并不能解决潜在问题。)

修改:这似乎是代码的相关部分。我当然没有自己写这个,我只能通过猜测可能发生的事情来追随它 - 我从来没有学过PHP的一个词。

的index.php

if ($_GET['do'] || $_POST['do']) {
    switch ($_GET['do']) {
        case 'rate':
             $sql = "SELECT ip FROM ".$_qdbs[tpfx]."votes WHERE id='".mysql_real_escape_string($_GET['q'])."' AND ip='$ip'"; 
             $a = $db->_sql($sql);
             $row = $db->fetch_row($a);
             if ($row['ip'] != $ip) {
                 if ($_GET['r'] == 'good') {
                     $sql = "UPDATE ".$_qdbs[tpfx]."quotes SET rating=rating+1 WHERE id='".mysql_real_escape_string($_GET['q'])."'";
                     $a = $db->_sql($sql);
                     $sql = "INSERT INTO ".$_qdbs[tpfx]."votes (id,ip) VALUES ('".mysql_real_escape_string($_GET['q'])."', '".mysql_real_escape_string($ip)."')";
                     $a = $db->_sql($sql);
                 }
                 elseif ($_GET['r'] == 'bad') {
                     $sql = "UPDATE ".$_qdbs[tpfx]."quotes SET rating=rating-1 WHERE id='".mysql_real_escape_string($_GET['q'])."'";
                     $a = $db->_sql($sql);
                     $sql = "INSERT INTO ".$_qdbs[tpfx]."votes (id,ip) VALUES ('".mysql_real_escape_string($_GET['q'])."', '".mysql_real_escape_string($ip)."')";
                     $a = $db->_sql($sql);
                 }
             }
             header("Location: ".$ref);
             break;
    }
...

quote_rate.tpl

[<a href="?do=rate&q=<?php echo $q_id;?>&r=good" title="Rate as good"><b>+</b></a>|<a href="?do=rate&q=<?php echo $q_id;?>&r=bad" title="Rate as bad"><b>-</b></a>]

修改:使用POST替换GET的想法来自this related question

使用AJAX进行投票无论如何我都想做,所以当然基于AJAX的解决方案也会很棒。

2 个答案:

答案 0 :(得分:2)

我假设你在谈论爬虫而不是垃圾邮件机器人。您不会通过切换到POST来阻止垃圾邮件机器人“点击”您的按钮。但是,听起来像是使用GET查询字符串的链接被“点击”。

GET / POST不是问题。链接是一个链接。您无法阻止抓取工具单击它们。表格是形式,你不能阻止投票操纵者或垃圾邮件机器人锤击你的表格。

要解决链接问题,您需要将表单替换为链接。大多数抓取工具通常不会发送表单,如果您告诉他们不要在robots.txt中抓取这些网页,则肯定不会由负责的表单发送。你甚至可以继续使用GET。你只需要使用一个表格。

<form action="?do=rate&q=<?php echo $q_id;?>&r=good">
    <input type="submit" name="up" value="up" />
</form>
<form action="?do=rate&q=<?php echo $q_id;?>&r=bad">
    <input type="submit" name="down" value="down" />
</form>

答案 1 :(得分:1)

我认为最适合您的解决方案(希望其他人有同感)是通过将进行投票的AJAX函数更改链接到每个+ - 符号的HTML代码,例如:

而不是使用此代码:

[<a href="?do=rate&q=<?php echo $q_id;?>&r=good" title="Rate as good"><b>+</b></a>|<a href="?do=rate&q=<?php echo $q_id;?>&r=bad" title="Rate as bad"><b>-</b></a>]

你会有这样的事情:

[<a href="javascript:rateQuote('good',<?php echo $q_id;?>)" title="Rate as good"><b>+</b></a>|<a href="javascript:rateQuote('bad',<?php echo $q_id;?>)" title="Rate as bad"><b>-</b></a>]  

JS函数看起来应该与此类似:

function rateQuote(vote,id) {
if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
else
  {// code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xmlhttp.onreadystatechange=function()
  {
  if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
               //if you want to include a 'success' message, this is the place
    }
  }
xmlhttp.open("GET","index.php?do=rate&q="+id+"r="+vote,true);
xmlhttp.send();
}

据我所知,通常,抓取工具不会运行javascript函数。但我不是百分百肯定。