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

PHP 利用 Session 防止頁面重複刷新與表單重複提交

     編輯:PHP 相關知識

前言

在 Web 開發中,防止用戶重複刷新頁面或重複提交表單是常見需求。本文介紹一種基於 PHP Session 結合 IP 地址與提交參數的防重複刷新機制,適用於表單提交、支付回調等場景。

核心原理

該方案的核心邏輯如下:

  1. 僅允許 POST 請求訪問目標頁面,直接訪問返回 404。
  2. 獲取客戶端真實 IP 地址(支援代理環境)。
  3. 將 IP、表單提交的關鍵參數進行 MD5 加密,生成唯一標識鍵值。
  4. 在 Session 中記錄該鍵值對應的時間戳。
  5. 判斷兩次請求間隔是否超過設定閾值(預設 30 秒),若未超過則阻擋請求並返回 404。

完整代碼實現

<?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 = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0';
        }
    } else {
        if (getenv('HTTP_X_FORWARDED_FOR')) {
            $ip = getenv('HTTP_X_FORWARDED_FOR');
        } elseif (getenv('HTTP_CLIENT_IP')) {
            $ip = getenv('HTTP_CLIENT_IP');
        } else {
            $ip = getenv('REMOTE_ADDR');
        }
    }

    preg_match("/[\d\.]{7,15}/", $ip, $onlineip);
    $ip = !empty($onlineip[0]) ? $onlineip[0] : '0.0.0.0';
    return $ip;
}

$reip = GetIP();

// 生成唯一標識:IP + 參數 MD5
$allowT = md5($reip . $fs1 . $fs2);

if (!isset($_SESSION[$allowT])) {
    $_SESSION[$allowT] = time();
} elseif (time() - $_SESSION[$allowT] > $allowTime) {
    $_SESSION[$allowT] = time();
} else {
    header('HTTP/1.1 404 Not Found');
    die('來自 ' . $ip . ' 的親,您刷新過快了');
}
?>

前端表單示例

對應的 HTML 表單頁面(a.html):

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>提交頁面</title>
</head>
<body>
    <form action="b.php" method="post">
        <input type="hidden" id="a" name="a" value="a"/>
        <input type="hidden" id="b" name="b" value="b"/>
        <button type="submit">提交</button>
    </form>
</body>
</html>

關鍵點解析

  • 參數區分性:除 IP 外加入表單參數($fs1、$fs2)生成鍵值,可區分同一 IP 不同業務提交,避免誤攔截。
  • Session 儲存:利用 Session 會話級儲存,無需資料庫,效能較好。
  • IP 獲取健壯性:兼容代理、負載均衡等環境下的真實 IP 獲取。
  • Referer 限制:文中提到可增加 Referer 判斷防跨站提交,但因可偽造且瀏覽器兼容性問題,建議配合 CSRF Token 使用。

適用場景與注意事項

適用於表單提交、支付回調、投票等需防重複操作的場景。注意:Session 依賴 Cookie,若用戶禁用 Cookie 則失效;分佈式環境需共享 Session 儲存(如 Redis)。生產環境建議結合資料庫唯一索引或分佈式鎖實現更可靠的冪等性保障。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved