避免垃圾表单🌐 Cloudflare Turnstile + Formspree 表单完整设置教程

避免垃圾表单 Cloudflare Turnstile + Formspree 表单完整设置

前言:使用 Turnstile 的目的

在网站表单中使用 Cloudflare Turnstile 主要目的是:

  1. 防止垃圾表单:阻挡自动提交的机器人和脚本,减少垃圾邮件
  2. 保护邮箱安全:避免邮箱被滥用
  3. 提高用户体验:相比传统 CAPTCHA,无需点击“我不是机器人”,自动分析行为
  4. 提高网站安全性:确保提交的表单来自真实用户

结合 Formspree + AJAX,可以实现 无刷新、快速提交,同时保证安全性和用户体验。


一、前提条件

  1. Cloudflare 账号,并在 Turnstile 中注册网站:

    • Sitekey(前端使用)
    • Secret key(后端验证)
  2. 支持 PHP 后端(用于验证 Turnstile token)
  3. 使用 Formspree 作为邮件服务

二、Cloudflare Turnstile 使用方法

  1. 登录 Cloudflare 打开 Cloudflare Dashboard

  2. 进入 Turnstile 页面

    • 左侧菜单:Security → Bots → Turnstile
  3. 注册站点

    • 点击 Add site
    • 填写:

      • Site name:自定义,用于识别
      • Domain:网站域名,例如 example.com
      • Widget Mode:选择 Managed(自动模式)
    • 点击 Save
  4. 获取 Key

    • Sitekey → 前端显示验证码
    • Secret key → 后端验证用户 token ⚠️ Secret key 必须保密,不可放前端
  5. 前端使用

    • 在表单中添加:

      <div class="cf-turnstile" data-sitekey="你的-sitekey"></div>
                                      
    • 引入 JS:

      <script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
                                      
  6. 后端验证

    • 用户提交表单时,会生成 cf-turnstile-response token
    • 后端发送请求到 Cloudflare:

      POST https://challenges.cloudflare.com/turnstile/v0/siteverify
                                          secret=你的-secret-key
                                          response=用户token
                                      
    • 验证成功才处理表单

三、Turnstile 的优势

  • 用户体验好:无需点击“我不是机器人”,自动分析行为
  • 轻量快速:加载速度快,对页面性能影响小
  • 隐私友好:不收集个人数据,符合 GDPR
  • 防止垃圾表单:有效阻挡自动脚本
  • 免费使用

四、前端 HTML 表单

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
                        <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
                        <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
                        <script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>

                        <form id="contact-form" action="submit.php" method="POST" class="container mt-3">
                        <div class="mb-3">
                        <input type="text" class="form-control" placeholder="Name" name="name" required>
                        </div>

                        <div class="mb-3">
                        <input type="email" class="form-control" placeholder="E-mail" name="email" required>
                        </div>

                        <div class="mb-3">
                        <textarea class="form-control" placeholder="Enter your message..." rows="6" name="message" required></textarea>
                        </div>

                        <!-- Honeypot 防垃圾 -->
                        <div style="display:none;">
                        <input type="text" name="_gotcha" tabindex="-1" autocomplete="off">
                        </div>

                        <!-- Turnstile 验证 -->
                        <div class="cf-turnstile mb-3" data-sitekey="你的-sitekey"></div>

                        <button type="submit" class="btn btn-warning w-100">Send Message</button>

                        <div id="form-status" class="mt-2"></div>
                        </form>
                    

五、前端 JS (AJAX 提交)

<script>
                        $(function() {
                          $("#contact-form").on("submit", async function(e){
                            e.preventDefault();
                            const $form = $(this);
                            const status = $("#form-status");
                            status.html("<p style='color:blue;'>⏳ 提交中,请稍候...</p>");

                            const data = new FormData(this);

                            // 获取 Turnstile token
                            const token = $('input[name="cf-turnstile-response"]').val();
                            if (!token) {
                              status.html("<p style='color:red;'>⚠️ 请先完成验证。</p>");
                              return;
                          }
                          data.append("cf-turnstile-response", token);

                          try {
                              const response = await fetch($form.attr("action"), {
                                method: "POST",
                                body: data
                            });
                            const result = await response.json();

                            if (result.success) {
                                status.html("<p style='color:green;'>✅ 提交成功,我们会尽快联系您!</p>");
                                $form[0].reset();
                                if (window.turnstile) turnstile.reset();
                            } else {
                                status.html("<p style='color:red;'>❌ 提交失败,请稍后再试。</p>");
                            }

                        } catch (error) {
                          status.html("<p style='color:red;'>⚠️ 网络错误,请检查连接。</p>");
                      }
                  });
              });
          </script>
      

六、后端 PHP 验证 Turnstile + 转发 Formspree

<?php
        header('Content-Type: application/json');

        $secret = "你的-secret-key";
        $token = $_POST['cf-turnstile-response'] ?? '';
        if (!$token) { echo json_encode(['success'=>false]); exit; }

        // 验证 Turnstile
        $verify = curl_init();
        curl_setopt($verify, CURLOPT_URL, "https://challenges.cloudflare.com/turnstile/v0/siteverify");
        curl_setopt($verify, CURLOPT_POST, true);
        curl_setopt($verify, CURLOPT_POSTFIELDS, http_build_query([
        'secret' => $secret,
        'response' => $token
        ]));
        curl_setopt($verify, CURLOPT_RETURNTRANSFER, true);
        $response = curl_exec($verify);
        curl_close($verify);

        $result = json_decode($response, true);
        if (!$result['success']) { echo json_encode(['success'=>false]); exit; }

        // 转发到 Formspree
        $formspree_url = "https://formspree.io/f/xxxxxx";
        $data = [
        'name' => $_POST['name'] ?? '',
        'email' => $_POST['email'] ?? '',
        'message' => $_POST['message'] ?? '',
        '_gotcha' => $_POST['_gotcha'] ?? ''
        ];

        $ch = curl_init($formspree_url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Accept: application/json']);
        curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        echo json_encode(['success'=>($http_code>=200 && $http_code<300)]);
        ?>
    

七、使用到的 CSS 和 JS

  • CSS

    • Bootstrap 5

      <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
                          
  • JS

    • jQuery(AJAX)

      <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
                          
    • Bootstrap JS(可选)

      <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
                          
    • Cloudflare Turnstile JS

      <script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
                          

八、流程概览

  1. 用户填写表单 + 完成 Turnstile 验证
  2. AJAX 提交表单到 submit.php
  3. PHP 后端验证 Turnstile token
  4. 验证通过后转发数据到 Formspree
  5. 前端显示 提交成功 / 失败 提示

Get in touch

Our Location

Hong Kong、Shenzhen 、Miami

Call us on

+(852) 6501 3956

Send message

[email protected]

Working Hours

Sat-Mon:10.00AM-5.00PM