无后端表单方案完全手册


静态网站不用写一行后端代码,把用户留言直接发到你的邮箱。

一、快速决策(30 秒选方案)

你的情况 选这个
免费、够用、异步不跳页,接受注册 Web3Forms(推荐)
看重老牌品牌和生态、需要 Dashboard 记录提交历史 Formspree
想要”一行 action 零注册”的极简方案 ❌ FormSubmit.co 已永久离线,此路不通(见第四节)

为什么不再推荐 FormSubmit.co?
它曾是最简单的无后端表单服务,但源服务器已不可访问,处于永久离线状态。此外,多个安全平台因其所有权信息不公开将其评为”可疑网站”,信任评分很低,已被多家安全机构列入黑名单,部分浏览器会将其拦截或误报为网络钓鱼。网上的旧教程全部失效,不要在任何项目中使用

二、方案一:Web3Forms

官网: https://web3forms.com
定位: 面向开发者的无后端表单 API,异步提交不跳页

核心参数

免费额度 250 提交/月
注册要求 必须(邮箱注册 → Dashboard 拿 Access Key)
提交方式 JS fetch() 异步 POST,无页面跳转
JS 依赖 必须
反垃圾 AI botcheck + Honeypot + 速率限制
自动回复 免费自带(Dashboard 开启 AutoResponder)
文件上传 ❌ 免费不支持,Pro 支持(≤3MB)
Pro 价格 $7/月(无限制 + 自定义域名 + 入站白名单)
Key 暴露 ⚠️ Access Key 会暴露在前端 HTML 中(无法避免)
数据保留 不存储,转发即删

注册与获取 Key

  1. 打开 https://web3forms.com → 输入邮箱注册
  2. 进入 Dashboard,复制 Access Key
  3. 在项目代码中把 YOUR_ACCESS_KEY 替换为真实 Key

HTML 表单(原生 POST,会跳页)

<form action="https://api.web3forms.com/submit" method="POST">
    <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY" />
    <input type="text" name="name" placeholder="您的姓名" required />
    <input type="email" name="email" placeholder="电子邮箱" required />
    <textarea name="message" placeholder="留言内容" required></textarea>
    <button type="submit">发送留言</button>
</form>

注意: 这种方式提交后会跳转到 Web3Forms 的成功页,用户体验较差。推荐使用下面的 JS 异步方式。

HTML 表单(配合 JS 异步,无跳页)

<form id="contactForm">
    <!-- 反垃圾 honeypot,必须加,否则被识别为垃圾提交 -->
    <input type="checkbox" name="botcheck" style="display:none;" />

    <input type="text" name="name" placeholder="您的姓名" required />
    <input type="email" name="email" placeholder="电子邮箱" required />
    <input type="text" name="subject" placeholder="主题" />
    <textarea name="message" placeholder="留言内容" required></textarea>
    <button type="submit">发送留言</button>
    <p id="formMsg" style="display:none;"></p>
</form>

关键: <input name="botcheck"> 是 Web3Forms 的 Honeypot 字段,不加会被识别为垃圾提交。

JavaScript 异步提交(FormData 方式)

const form = document.getElementById("contactForm");
const formMsg = document.getElementById("formMsg");
const submitBtn = form.querySelector('button[type="submit"]');
const ACCESS_KEY = "YOUR_ACCESS_KEY"; // ⚠️ 替换为 Dashboard 中的真实 Key

form.addEventListener("submit", async function (e) {
    e.preventDefault();

    const formData = new FormData(form);
    formData.append("access_key", ACCESS_KEY);

    const originalText = submitBtn.textContent;
    submitBtn.textContent = "发送中...";
    submitBtn.disabled = true;

    try {
        const res = await fetch("https://api.web3forms.com/submit", {
            method: "POST",
            body: formData,
        });

        const data = await res.json();

        if (data.success) {
            formMsg.textContent = "留言已发送,我们会尽快回复!";
            formMsg.style.color = "#4ade80";
            formMsg.style.display = "block";
            form.reset();
        } else {
            throw new Error(data.message || "提交失败");
        }
    } catch (err) {
        formMsg.textContent = "发送失败,请稍后重试或直接发送邮件至 your-email@example.com";
        formMsg.style.color = "#ef4444";
        formMsg.style.display = "block";
    } finally {
        submitBtn.textContent = originalText;
        submitBtn.disabled = false;
    }
});

JavaScript 异步提交(JSON 方式)

const form = document.getElementById("contactForm");
const formMsg = document.getElementById("formMsg");
const ACCESS_KEY = "YOUR_ACCESS_KEY";

form.addEventListener("submit", async function (e) {
    e.preventDefault();
    const btn = form.querySelector('button[type="submit"]');
    btn.textContent = "发送中...";
    btn.disabled = true;

    try {
        const res = await fetch("https://api.web3forms.com/submit", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({
                access_key: ACCESS_KEY,
                ...Object.fromEntries(new FormData(form)),
            }),
        });
        const data = await res.json();
        if (data.success) {
            formMsg.textContent = "留言已发送,我们会尽快回复!";
            formMsg.style.color = "#4ade80";
            formMsg.style.display = "block";
            form.reset();
        } else {
            throw new Error(data.message || "提交失败");
        }
    } catch (err) {
        formMsg.textContent = "发送失败,请稍后重试或直接发送邮件至 your-email@example.com";
        formMsg.style.color = "#ef4444";
        formMsg.style.display = "block";
    } finally {
        btn.textContent = "发送留言";
        btn.disabled = false;
    }
});

FormData vs JSON: 两种方式都可以,FormData 方式更简洁,JSON 方式可以更灵活地添加额外字段。

React 实现

import { useState } from "react";

export default function ContactForm() {
    const [result, setResult] = useState("");
    const [isSuccess, setIsSuccess] = useState(false); // 提交结果是否成功:true 绿字 / false 红字,用于结果提示配色
    const [isSubmitting, setIsSubmitting] = useState(false); // 是否正在提交:true 时禁用按钮并显示"发送中...",防重复提交
    const ACCESS_KEY = "YOUR_ACCESS_KEY"; // ⚠️ 替换为 Dashboard 中的真实 Key

    const onSubmit = async event => {
        event.preventDefault();
        setIsSubmitting(true);

        const formData = new FormData(event.target);
        formData.append("access_key", ACCESS_KEY);

        try {
            const response = await fetch("https://api.web3forms.com/submit", {
                method: "POST",
                body: formData,
            });

            const data = await response.json();

            if (data.success) {
                setResult("留言已发送,我们会尽快回复!");
                setIsSuccess(true);
                event.target.reset();
            } else {
                setResult("发送失败,请稍后重试");
                setIsSuccess(false);
            }
        } catch (error) {
            setResult("发送失败,请稍后重试");
            setIsSuccess(false);
        } finally {
            setIsSubmitting(false);
        }
    };

    return (
        <form onSubmit={onSubmit}>
            <input
                type="text"
                name="name"
                placeholder="您的姓名"
                required
                disabled={isSubmitting}
            />
            <input
                type="email"
                name="email"
                placeholder="电子邮箱"
                required
                disabled={isSubmitting}
            />
            <textarea
                name="message"
                placeholder="留言内容"
                required
                disabled={isSubmitting}
            ></textarea>
            <button type="submit" disabled={isSubmitting}>
                {isSubmitting ? "发送中..." : "发送留言"}
            </button>
            {result && <p style={{ color: isSuccess ? "#4ade80" : "#ef4444" }}>{result}</p>}
        </form>
    );
}

三种实现方式对比:

  • 纯 HTML:最简单,但会跳页,用户体验差
  • 纯 JS:异步无跳页,适合传统网页
  • React:组件化,状态管理清晰,适合现代前端框架项目

高级配置

自定义邮件主题: 在 Web3Forms Dashboard → Form Settings 中设置 subject,多个站点可用不同主题区分来源。

自动回复(免费): Dashboard → Form Settings → 开启 AutoResponder,用户提交后收到自动确认邮件。

自定义成功跳转: 在 fetch body 中添加 redirect 字段:

body: JSON.stringify({
    access_key: ACCESS_KEY,
    redirect: "https://你的域名/thanks.html",
    ...Object.fromEntries(new FormData(form)),
});

但更推荐用异步 JS 控制成功提示,比跳页体验更好。

三、方案二:Formspree(备选)

官网: https://formspree.io
定位: 最老牌的无后端表单服务,50 万+ 用户,生态最成熟
适合: 需要 Dashboard 管理提交记录、需要集成 Slack / Notion 等工具的场景

核心参数

免费额度 50 提交/月
注册要求 必须(邮箱注册 → 创建表单 → 获取 endpoint)
提交方式 JS fetch() 异步 POST(推荐)或原生 form POST
JS 依赖 推荐有(不加则会跳页到 Formspree 成功页)
反垃圾 Formshield ML 过滤 + reCAPTCHA + 自定义规则
数据保留 ⚠️ 免费版仅 30 天(超期自动删除,无法恢复)
文件上传 ❌ 免费版不支持
自动回复 ❌ 免费版不支持
Dashboard ✅ 丰富:搜索、导出 CSV、查看详情
第三方集成 ✅ Slack、Notion、Airtable、Google Sheets 等 25+
付费起步 $10/月(年付,200 提交/月,无限归档,1GB 上传)

注册与获取 Endpoint

  1. 打开 https://formspree.io → 注册
  2. 创建新表单 → 获得类似 https://formspree.io/f/xxxxxxxx 的 endpoint
  3. 验证邮箱(首次收邮件点确认)

HTML + JS(fetch 方式,无跳页)

<form id="contactForm">
    <input type="text" name="name" placeholder="您的姓名" required />
    <input type="email" name="email" placeholder="电子邮箱" required />
    <textarea name="message" placeholder="留言内容" required></textarea>
    <button type="submit">发送留言</button>
    <p id="formMsg" style="display:none;"></p>
</form>

<script>
    const form = document.getElementById("contactForm");
    const formMsg = document.getElementById("formMsg");

    form.addEventListener("submit", async function (e) {
        e.preventDefault();
        const btn = form.querySelector("button");
        btn.textContent = "发送中...";
        btn.disabled = true;

        try {
            // ⚠️ Formspree 用 FormData,不是 JSON;Accept header 必须带
            const res = await fetch("https://formspree.io/f/YOUR_FORM_ID", {
                method: "POST",
                headers: { Accept: "application/json" },
                body: new FormData(form),
            });
            if (res.ok) {
                formMsg.textContent = "留言已发送,我们会尽快回复!";
                formMsg.style.color = "#4ade80";
                formMsg.style.display = "block";
                form.reset();
            } else {
                throw new Error("提交失败");
            }
        } catch (err) {
            formMsg.textContent = "发送失败,请稍后重试或直接发送邮件至 your-email@example.com";
            formMsg.style.color = "#ef4444";
            formMsg.style.display = "block";
        } finally {
            btn.textContent = "发送留言";
            btn.disabled = false;
        }
    });
</script>

与 Web3Forms JS 的关键区别:

  • 两者都支持 FormDataJSON 两种提交方式(本文 Web3Forms 主示例用 FormData,亦可改用 JSON.stringify,见上方 JSON 方式)。
  • Formspree 必须带 Accept: application/json,否则返回 HTML 跳页;Web3Forms 两种方式都不需要该头。
  • 判断成功:Formspree 用 res.ok,Web3Forms 用响应体里的 data.success 字段判断(即使 HTTP 200 也可能 success:false)。

免费版关键限制

限制 影响
数据仅保留 30 天 超期的提交记录永久丢失,无法恢复
无文件上传 用户无法提交附件
仅 2 个邮箱 只能关联两个收件邮箱
无自动回复 用户提交后不会收到确认邮件
50 提交/月 比 Web3Forms 的 250/月 少了 5 倍

如果你不会每天登录 Dashboard 导出数据,Formspree 免费版的 30 天归档窗口是个硬伤。

四、已关停 — FormSubmit.co

原域名: https://formsubmit.co
状态: 源服务器已不可访问,处于永久离线状态。

FormSubmit.co 曾是静态网站表单的”杀手级应用”——无需注册,一行 action="https://formsubmit.co/你的邮箱" 搞定,极低学习成本。其核心机制是通过 HTML 隐藏字段配置行为,所有配置都在 <input type="hidden" name="_xxx" value="..."> 中完成。

⚠️ 安全隐患

除了服务已离线外,FormSubmit.co 还被多个安全平台列为可疑网站

  • 信任评分极低:因所有权信息公开不透明,多家安全平台将其评为”不可信”
  • 已被拉黑:多家安全机构将其列入黑名单
  • 浏览器拦截:部分浏览器会拦截其页面或误报为网络钓鱼
  • 敏感数据风险:如果曾有用户在你的表单中输入过邮箱等个人信息,这些数据经过了不受信任的第三方中转

结论: 即便将来该域名恢复访问,也不应再使用。它将用户提交的表单数据经由不可信实体转发,存在隐私泄漏风险。

关停教训

不要依赖无收益商业模式的免费服务,迁移成本在关停那一刻才真正计算清楚。 网上的旧教程全部失效。

旧版隐藏字段速查(仅供历史参考,已全部失效)

字段 说明
_captcha false 跳过验证码(默认开启)
_subject 任意字符串 邮件主题
_template table / plain 邮件格式,推荐 table
_next URL 提交成功后跳转地址
_cc 邮箱地址 抄送
_autoresponse 文本 自动回复(需 Pro)
_honey 任意 反垃圾蜜罐字段名
_replyto 邮件字段名 回复时指向提交者邮箱
_webhook URL 提交后回调 Webhook(Pro)

迁移路线:FormSubmit.co → Web3Forms

旧功能 Web3Forms 替代方式
零注册 注册一次 → 拿 Access Key → 再也不需要注册
一行 action 注册一次 → Key 填入 JS → 永久使用
50 免费/月 250 免费/月(5 倍于旧版)
_captcha 内置 botcheck(AI 反垃圾),无需手动配置验证码
_subject Dashboard 配置 或 JSON body 中 subject 字段
_template Dashboard 可配置 HTML 邮件模板
_next 跳转 JSON body 中 redirect 字段 或 JS then() 控制(推荐后者)
_cc Dashboard 配置
_autoresponse 免费自带(Dashboard 开启 AutoResponder)
_honey 内置 Honeypot(<input name="botcheck">),不建议额外加

核心建议: 如果你有基于 FormSubmit.co 搭建的存量项目,迁移到 Web3Forms 是最平滑的路径——功能覆盖最完整,免费额度更高,且唯一需要改动的是把 HTML 隐藏字段替换为 JS fetch + Dashboard 配置。

五、FormSubmit.site(不推荐)

官网: https://formsubmit.site

FormSubmit.site 是一个需要注册的商业化付费表单服务(按提交量付费,$10 起),采用 CLI + Dashboard 双模操作,运营者联系邮箱为 nikunj@formsubmit.site。目前没有公开信息直接表明它与 FormSubmit.co 属于同一实体,从产品形态看两者是独立项目:

  • FormSubmit.co(已离线):经典免费表单后端,无需注册,HTML action 直接填邮箱
  • FormSubmit.site(商业化):需要注册账户,按量付费,提供仪表盘和数据管理

FormSubmit.site 不兼容旧版 _xxx 隐藏字段体系(无 _captcha_next_cc_autoresponse 等),反垃圾使用启发式评分而非验证码,是一款从零设计的独立新产品。考虑到它是 CLI 命令行产品、无免费层、且版本仍为 v0.1.1,对于静态网站表单需求来说,Web3Forms 或 Formspree 是更直接的选择

六、综合对比

6.1 核心参数

维度 Web3Forms Formspree
官网 web3forms.com formspree.io
免费额度 250 封/月 50 封/月
注册要求 必须注册,获取 Access Key 必须注册,创建表单 → 获取 endpoint
入门成本 $0 $0
Pro 起步 $7/月(无限量 + 自定义域名) $10/月(年付,200 提交/月)
提交方式 JS fetch() 异步 POST(JSON body) JS fetch() 异步 POST(FormData body)或原生 form
JS 依赖 必须(fetch + JSON) 推荐(fetch + FormData);也可原生 form(会跳页)
验证码 内置 botcheck(AI 反垃圾)+ Honeypot ML Formshield + reCAPTCHA
邮件模板 可自定义 HTML 模板 基础模板,Dashboard 可配置

6.2 功能特性

特性 Web3Forms Formspree
文件上传 Pro 支持,免费 ≤3MB ❌ 免费版不支持
自动回复(给提交者) 免费自带(Dashboard 开启 AutoResponder) ❌ 付费功能
成功回调 / 跳转 JS then() 自定义;也可 redirect 字段 JS then() 或原生 form
抄送(CC) Dashboard 配置 Dashboard 配置
Honeypot 反垃圾 不建议额外加(冲突内置 botcheck) ✅ 支持自定义隐藏字段
自定义邮件主题 subject 字段或 Dashboard Dashboard 配置
多站点区分 Access Key 绑定域名 创建多个表单
入站白名单 Pro 功能 企业版功能
数据保留(免费) 不存储(转发即删) ⚠️ 仅 30 天,超期删除
第三方集成 基础(Zapier 等) 25+(Slack、Notion、Airtable、Google Sheets 等)
Dashboard ✅ 基础(提交记录、配置) ✅ 丰富(搜索、导出 CSV、详情)
CLI / AI 工具链

6.3 用户体验

维度 Web3Forms Formspree
提交体验 异步无刷新,停留在当前页 异步(fetch)无刷新;原生 form 会跳页
自定义成功页 ✅ JS 完全控制 ✅ JS 控制
首次启动流程 注册 → 拿 Key → 写代码 注册 → 创建表单 → 拿 endpoint → 验证邮箱
收件箱改动 无需(转发即达) 首次需点确认链接
学习成本 中等(需了解 fetch API) 中等(需了解 fetch API)
调试难度 浏览器 DevTools Network 面板 浏览器 DevTools Network 面板

6.4 安全 & 隐私

维度 Web3Forms Formspree
Key / Token 暴露 ⚠️ Access Key 会暴露在前端 HTML 中 ⚠️ Form ID 会暴露在前端
垃圾邮件防护 AI botcheck + 速率限制 ML Formshield + reCAPTCHA + 自定义规则
可限制提交来源 Pro 可限制白名单域名 企业版可限制
数据存储策略 不存储(转发即删) 不存储(转发即删)
GDPR 合规 ✅ 合规 ✅ 合规
稳定性 成熟 最老牌(50 万+ 用户)

七、切换指南

7.1 迁移到 Web3Forms(从任意方案)

  1. 注册 Web3Formshttps://web3forms.com → 拿 Access Key
  2. 改 HTML 表单
    • 删除 action="..." 改为无 action 的 <form id="contactForm">
    • 删除所有 _xxx 隐藏字段(原 FormSubmit.co 用法)
    • 添加 <input type="checkbox" name="botcheck" style="display:none;">(必须)
  3. 替换 JS:用本文第二节的异步代码
  4. 填入 Key:把 YOUR_ACCESS_KEY 换成真实 Key
  5. 测试:提交一条留言,检查目标邮箱是否收到

7.2 切换到 Formspree(从 Web3Forms)

  1. 注册 Formspree → 创建表单 → 拿到 https://formspree.io/f/xxxxxxxx
  2. 改 HTML:删除 botcheck 字段,表单无需特殊字段
  3. 替换 JS:把 fetch 目标换为 Formspree endpoint;body 改用 new FormData(form);添加 Accept: application/json header;判断改为 res.ok
  4. 验证邮箱:首次提交后去收件箱点确认
  5. 测试:再提交,确认邮件正常送达

八、故障排查

Web3Forms

  • Access Key 是否已填? — 确认 JS 中 YOUR_ACCESS_KEY 已替换为真实 Key
  • botcheck 字段是否存在? — 表单中必须有 <input name="botcheck" style="display:none;">
  • Network 面板检查 — 看 api.web3forms.com/submit 返回的 data.success 是否为 true
  • Dashboard 检查 — 登录 Web3Forms 查看是否有提交记录,或被反垃圾拦截
  • 垃圾箱 — 首次注册确认邮件是否在邮箱垃圾箱

Formspree

  • 表单 ID 是否正确? — endpoint 中 /f/xxxxxxxx 与 Dashboard 一致
  • 邮箱是否已验证? — 首次收到激活邮件需点击确认
  • Accept header — fetch 是否带 'Accept': 'application/json'(不带会跳页)
  • body 格式 — 是否用 new FormData(form) 而非 JSON.stringify
  • Dashboard 检查 — 登录 Formspree 查看提交记录

通用排查

  • name 属性 — 所有 <input><textarea> 都必须有 name 属性
  • 垃圾箱 — 首次邮件经常被误判为垃圾邮件
  • 网络问题 — 检查浏览器控制台有无 CORS 或网络错误
  • 服务冲突 — 确保没有 Netlify Forms 等其他服务拦截表单提交

九、速查卡片

Web3Forms

注册 → 拿 Access Key → JS fetch('https://api.web3forms.com/submit', {JSON body})
必须加 <input name="botcheck" style="display:none;">(Honeypot,防垃圾)
免费 250/月 | Pro $7/月
优势:异步不跳页 | 自动回复免费 | 250/月够用 | 配置简单
劣势:Key 暴露在前端 | 必须 JS

Formspree(备选)

注册 → 创建表单 → fetch('https://formspree.io/f/ID', {FormData + Accept:json})
免费 50/月(数据仅保留 30 天)| Pro $10/月
优势:最老牌 | Dashboard 丰富 | 25+ 集成
劣势:免费版 30 天删数据 | 无自动回复 | 无文件上传 | 额度少

文章作者: 弈心
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 弈心 !
评论
 本篇
无后端表单方案完全手册 无后端表单方案完全手册
静态网站无需编写后端即可收集用户留言并推送到邮箱的完整方案手册,对比 Web3Forms、Formspree、FormSubmit 等服务的用法、额度与常见坑点。
2026-07-24
下一篇 
静态网站表单推送到微信:现成服务与自建方案完全指南 静态网站表单推送到微信:现成服务与自建方案完全指南
梳理静态网站(Hexo/VitePress/Docsify)表单提交后实时推送到微信的免费与自建方案,对比 Server酱、pushplus、Wecom酱、Go-WXPush 等渠道的额度、特点与适用场景。
2026-07-24
  目录