PHP实现网站防频繁刷新限制的方法

沿途有光
沿途有光
发布时间:2026-10-14 | 4人浏览过
原创

频繁的页面刷新会导致数据库连接耗尽和服务器负载激增,尤其是对于内容驱动的站点如WordPress。通过PHP结合Session机制,可以有效限制同一用户在短时间内的请求频率。本文汇总了三种常见的防刷新实现方式,重点分析了代码执行位置对用户体验的影响。

防刷新的核心逻辑与准备条件

所有防刷新方案的基础都是利用服务器的 Session 存储状态。当用户首次访问时,记录当前时间戳;在后续请求中,计算当前时间与记录时间的差值。若差值小于设定的阈值,则视为刷新攻击,执行拦截或忽略操作。

重要前提:在使用以下代码前,必须在文件顶部调用 session_start() 以初始化会话。同时,需确保服务器环境支持Session写入权限。

具体实现方法

第1步:基于IP与参数的长周期限流

目的:适用于需要较长冷静期(如半小时)的场景,通过生成唯一哈希标识区分不同用户或参数请求。

操作说明:

  1. 获取客户端IP地址。
  2. 组合IP、自定义密钥(k)和时间(t)生成MD5哈希值作为Session键名,避免冲突。
    $allowT = md5($ip.$k.$t);
  3. 检查 $_SESSION[$allowT] 是否存在且未过期。
  4. 若未过期,设置变量 $refresh = false;否则更新Session时间并标记为允许刷新。

关键参数:$allowTime = 1800(设定1800秒,即30分钟)。此方法适合低频高风险操作。

第2步:基于全局时间的短周期阻断

目的:快速响应毫秒级或秒级的暴力刷新,保护资源不被瞬间耗尽可能。

操作说明:

  1. 定义安全间隔时间,例如 $allow_sep = "2"(秒)。
      
    session_start();      
    $k=$_GET['k'];      
    $t=$_GET['t'];      
    $allowTime = 1800;//防刷新时间      
    $ip = get_client_ip();      
    $allowT = md5($ip.$k.$t);      
    if(!isset($_SESSION[$allowT]))      
    {      
        $refresh = true;      
        $_SESSION[$allowT] = time();      
    }elseif(time() - $_SESSION[$allowT]>$allowTime){      
        $refresh = true;      
        $_SESSION[$allowT] = time();      
    }else{      
        $refresh = false;      
    }      
    ?>
  2. 比较当前时间 time() 与上次记录时间。若间隔小于设定值,直接调用 exit() 中断脚本,输出提示信息。
    session_start(); 
    $allow_sep = "2"; 
    if (isset($_SESSION["post_sep"])) 
    {
    if (time() - $_SESSION["post_sep"] < $allow_sep)
     {
     exit("请不要频繁刷新,休息2秒再刷新吧");
     }
     else 
     {
    $_SESSION["post_sep"] = time();
     }
    }
     else 
     {
    $_SESSION["post_sep"] = time();
    }
    ?>

第3步:基于隐藏令牌的提交验证

目的:防止非正常流程下的直接刷新或伪造请求,常用于表单提交流程。

操作说明:

  1. 生成一个随机数作为令牌(Tag),并将其存储在Session中和页面上的隐藏域中。
    $v = mt_rand(1,10000);
    $_SESSION[status] = $v;
  2. 前端表单携带该Token:
    <form method="post" name="magic" action="f5.php">
    <input type="hidden" name="tag" value="<?= $v ?>">
    <input type=text name="name">
    <input type="submit" value="submit">
    </form>
  3. 后端验证提交的 tag 是否与Session中存储的一致。一致则处理数据,不一致则拒绝。
    if(!emptyempty($_POST[name])){ 
       $data = $_POST[name]; 
       $tag = $_POST[tag]; 
       if($_SESSION[status]==$tag){ 
         echo $data;
      }else{ 
         echo "不允许刷新!";
      } 
    } 

代码部署的最佳实践

防刷新代码的执行位置直接影响用户体验和防护效果。如果代码放在页面底部(Footer),用户可能会看到完整的页面加载后,最后才被提示“请勿刷新”,这未能起到实时拦截作用。

推荐方案:引入独立头部文件

为了保持代码整洁且不影响主业务逻辑,建议将防刷新逻辑封装在一个独立的PHP文件中(如 forbiddenCC.php),并在主题的最外层模板头部进行引用。

操作步骤:

  1. 新建 forbiddenCC.php 文件,放入包含上述防刷新逻辑的代码块。
  2. 在主题的全局头部文件(通常是 header.php)的最顶端添加包含语句:
    <?php 
    include('includes/forbiddenCC.php'); 
    ?>
  3. 确保此引用位于所有HTML输出之前,以便在脚本早期阶段判断是否终止请求。

排查与注意事项

  • 缓存干扰:如果使用了对象缓存或页面缓存,Session可能无法实时生效。此时需配合CDN层的WAF规则或Nginx limit_req模块进行更底层的频率限制。
    nginx -s reload
  • 移动端适配:部分移动浏览器在唤醒应用时会触发重载,需适当放宽局部刷新判定或增加白名单机制。
    cache-control: no-cache
  • 调试技巧:可通过观察 $_COOKIE 中的PHPSESSID变化来确认Session是否正常工作。若发现无Cookie产生,请检查服务器路径权限。
    setcookie('test', 'value')

以上就是PHP防止网站被频繁刷新限制的详细内容,更多关于PHP防刷新技术应用的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表