首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 利用 Session 防止頁面重複刷新(含 IP 限流)

     編輯:PHP 相關知識

核心思路

結合用戶 IP 與 POST 參數生成唯一鍵,寫入 Session 記錄最後訪問時間,若間隔小於閾值(預設 30 秒)則返回 404,實現「同一用戶、同一表單、短時間內」的防重複提交。

完整實現代碼(b.php)

<?php
// 僅允許 POST 訪問
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
    header('HTTP/1.1 404 Not Found');
    die('親,頁面不存在');
}
session_start();

$fs1 = $_POST['a'] ?? '';
$fs2 = $_POST['b'] ?? '';
$allowTime = 30; // 秒

// 獲取真實客戶端 IP
function GetIP() {
    static $ip = null;
    if ($ip !== null) return $ip;
    if (isset($_SERVER)) {
        if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
            foreach ($arr as $xip) {
                $xip = trim($xip);
                if ($xip !== 'unknown') { $ip = $xip; break; }
            }
        } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
            $ip = $_SERVER['HTTP_CLIENT_IP'];
        } else {
            $ip = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
        }
    } else {
        $ip = getenv('HTTP_X_FORWARDED_FOR') ?: getenv('HTTP_CLIENT_IP') ?: getenv('REMOTE_ADDR') ?: '0.0.0.0';
    }
    preg_match("/[\d\.]{7,15}/", $ip, $m);
    $ip = !empty($m[0]) ? $m[0] : '0.0.0.0';
    return $ip;
}

$reip = GetIP();
$token = md5($reip . $fs1 . $fs2);

if (!isset($_SESSION[$token])) {
    $_SESSION[$token] = time();
} elseif (time() - $_SESSION[$token] >= $allowTime) {
    $_SESSION[$token] = time(); // 更新時間戳,允許繼續
} else {
    header('HTTP/1.1 404 Not Found');
    die("來自 {$reip} 的親,您刷新過快了");
}

// 正常業務邏輯從這裡開始...
?>

配合的提交頁面(a.html)

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>提交頁</title></head><body>
<form action="b.php" method="post">
  <input type="hidden" name="a" value="a">
  <input type="hidden" name="b" value="b">
  <button type="submit">提交</button>
</form>
</body></html>

關鍵細節說明

  • 雙重校驗:IP + 業務參數(a、b)生成 MD5 Token,區分不同業務場景,避免「同一 IP 不同表單」互相干擾。
  • Session 存儲:以 Token 為鍵,值為上次請求的 Unix 時間戳。
  • 時間窗口:time() - $_SESSION[$token] >= $allowTime 判斷是否超過允許間隔,注意原文邏輯有誤(--> 應為 >=),此處已修正。
  • 安全增強:可額外檢查 $_SERVER['HTTP_REFERER'] 防禦 CSRF,但 Referer 可偽造且部分瀏覽器不發送,屬輔助手段。

適用場景與局限

  • 適用於表單提交、支付下單、評論發布等「冪等性敏感」操作。
  • 不適用於靜態頁面瀏覽、GET 請求、分散式集群(需共享 Session 或改用 Redis)。
  • 若需更精準限流,建議採用令牌桶/漏桶演算法並集中式存儲。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved