【问题标题】:Converting GET to POST to avoid bots from messing up votes将 GET 转换为 POST 以避免机器人弄乱投票
【发布时间】:2024-01-23 11:53:01
【问题描述】:

我正在运行一个使用 qdbs 1.10 来提供基于 PHP 的带投票报价数据库的站点。投票是通过 GET 实现的,导致机器人意外地对报价进行投票。为避免这种情况,我想将 GET 请求转换为 POST。

我是 PHP 和一般 Web 开发的新手。是否有可能以最少的知识来执行这个机会?有什么可以遵循的模式,或者你有一些关于如何去做的提示吗?

(我正在更改 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>]

编辑: 将 GET 替换为 POST 的想法来自 this related question

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

【问题讨论】:

  • 你能提供给我们当前的PHP代码吗?将其从 GET 更改为 POST 应该很容易
  • 这不是 PHP 问题。在 HTML 代码中进行 GET 到 POST 的转换。去图
  • 这是一个 PHP 问题,因为他还必须编辑 PHP 代码才能读取 $_POST 字段而不是 $_GET 字段。

标签: php html post get robots.txt


【解决方案1】:

我假设您说的是爬虫而不是垃圾邮件机器人。您不会通过切换到 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>

【讨论】:

  • 大量内容会影响您的表单。将表格放在页面上一天,我希望它会被“填写”十几次。即使您只有提交按钮,它也会一直受到机器人测试电子邮件中继的影响。
  • @Brad:我已经在回答中提到了这个问题。然而,在他的案例中,谷歌抓取工具正在点击他的链接。
  • 您能否添加一个使用表单的代码的示例?
【解决方案2】:

我认为最适合您的解决方案(希望其他人也有同感)是通过将进行投票的 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 函数。但我不是 100% 确定。

【讨论】:

  • 这不包括没有JS的人。
  • 我也相信基于 js 的链接通常会阻止机器人跟踪它们。我从没学过 js,但我想我可以按照你的代码示例进行操作,我会尝试将其添加到网站中。
  • 您可能会发现在 标记之间添加该 js,实际上会为报价单投票,但不会在有人投票后删除 [+\-] 符号。在这种情况下,您可能希望在我在代码中为成功消息所做的注释之后添加这一行:window.location.reload();
  • 一些爬虫运行Javascript。 AJAX 不是这个问题的答案。您以这种方式发出与使用简单链接相同的请求。
  • 我认为代码示例中r= 前面缺少&amp;
最近更新 更多