You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP简易联系表单反垃圾邮件优化方案求助

纯PHP反垃圾邮件优化方案

一、强化Session绑定的表单验证

机器人常绕过前端直接发送POST请求,通过Session绑定请求能有效拦截这类行为:

  1. 在表单生成页面初始化Session并生成随机令牌:
session_start();
// 标记表单有效状态
$_SESSION['form_valid'] = true;
// 生成随机令牌
$_SESSION['form_token'] = bin2hex(random_bytes(16));
  1. 在表单中添加隐藏的令牌字段:
<input type="hidden" name="form_token" value="<?php echo $_SESSION['form_token']; ?>">
  1. 在邮件处理脚本中验证令牌与Session状态:
session_start();
// 验证表单有效性与令牌匹配
if (!isset($_SESSION['form_valid']) || !isset($_POST['form_token']) || $_POST['form_token'] !== $_SESSION['form_token']) {
    exit('无效请求');
}
// 验证后销毁Session标记,防止重复提交
unset($_SESSION['form_valid']);
unset($_SESSION['form_token']);

二、优化提交时长校验逻辑

单纯的最小时长校验不够,需同时限制最大时长,避免机器人长时间持有表单后提交:

  1. 表单加载时记录时间到Session:
session_start();
$_SESSION['form_load_time'] = time();
  1. 处理脚本中校验时间范围(示例:5秒~30分钟):
session_start();
$submit_interval = time() - $_SESSION['form_load_time'];
if ($submit_interval < 5 || $submit_interval > 1800) {
    exit('请求超时或提交过快');
}
unset($_SESSION['form_load_time']);

三、强化内容特征拦截

针对你提到的“SPAM”开头主题及垃圾邮件共性特征,添加精准拦截规则:

  1. 直接拦截主题以SPAM开头的提交:
$subject = trim($_POST['subject']);
if (stripos($subject, 'SPAM') === 0) {
    exit('垃圾内容拦截');
}
  1. 拦截包含大量大写字母、异常链接的内容:
$message = $_POST['message'];
// 拦截连续10个以上大写字母的内容
if (preg_match('/[A-Z]{10,}/', $message)) {
    exit('垃圾内容拦截');
}
// 拦截包含3个及以上外部链接的内容
preg_match_all('/https?:\/\/\S+/', $message, $matches);
if (count($matches[0]) >= 3) {
    exit('垃圾内容拦截');
}
  1. 校验内容长度合理性:
if (strlen($message) < 10 || strlen($message) > 10000) {
    exit('内容长度异常');
}

四、添加IP提交频率限制

限制同一IP在指定时间内的提交次数,降低垃圾邮件批量发送概率:

session_start();
$client_ip = $_SERVER['REMOTE_ADDR'];
// 初始化提交计数Session
if (!isset($_SESSION['submit_counts'])) {
    $_SESSION['submit_counts'] = [];
}
// 1小时内最多允许3次提交
$current_time = time();
$time_window = 3600;
$max_submits = 3;
if (isset($_SESSION['submit_counts'][$client_ip])) {
    $last_submit_time = $_SESSION['submit_counts'][$client_ip]['time'];
    $submit_count = $_SESSION['submit_counts'][$client_ip]['count'];
    if ($current_time - $last_submit_time < $time_window) {
        if ($submit_count >= $max_submits) {
            exit('提交过于频繁,请稍后重试');
        }
        $_SESSION['submit_counts'][$client_ip]['count']++;
    } else {
        $_SESSION['submit_counts'][$client_ip] = ['count' => 1, 'time' => $current_time];
    }
} else {
    $_SESSION['submit_counts'][$client_ip] = ['count' => 1, 'time' => $current_time];
}

五、优化陷阱字段设计

普通隐藏字段易被机器人识别,改用迷惑性字段名提升拦截效果:

  1. 在表单中添加陷阱字段(用CSS隐藏,无需JS):
<div style="display:none;">
    <label for="website">网站(请勿填写)</label>
    <input type="text" name="website" id="website">
</div>
  1. 处理脚本中检查陷阱字段:
if (!empty(trim($_POST['website']))) {
    exit('垃圾内容拦截');
}

六、强化HTTP请求合法性校验

通过请求头过滤非本站来源的提交(虽可伪造,但能增加机器人攻击成本):

$allowed_domains = ['your-domain.com', 'www.your-domain.com'];
if (isset($_SERVER['HTTP_REFERER'])) {
    $referer_host = parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST);
    if (!in_array($referer_host, $allowed_domains)) {
        exit('无效请求来源');
    }
}

七、严格校验表单字段格式

过滤格式异常的字段,拦截机器人自动填充的无效数据:

// 校验邮箱格式
$email = trim($_POST['email']);
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    exit('邮箱格式无效');
}
// 校验姓名(仅允许字母、空格、部分特殊字符)
$name = trim($_POST['name']);
if (!preg_match('/^[a-zA-Z\s\-\']+$/', $name)) {
    exit('姓名格式无效');
}

内容的提问来源于stack exchange,提问作者Nathan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 22:54:18