跳转到内容
FFormhook
返回博客

博客

Netlify Forms 替代方案:一个到处都能用的表单后端

· 1 分钟阅读

Netlify Forms 确实是一项方便的功能--前提是您一直留在 Netlify 上。它内置于该平台的构建流程中,所以表单"直接就能用",不需要任何外部服务。问题就出在这句话的前半部分:它之所以能用,是因为 Netlify 的构建步骤在背后做了这些工作,这意味着表单被悄悄地与托管平台绑定在了一起。一旦迁移网站,表单也会跟着失效。

Netlify Forms 到底要求什么

Netlify Forms 不是一个通用的 HTML 功能--它是在构建时被检测到的。您在 <form> 标签上添加 data-netlify="true",Netlify 的构建步骤会扫描已部署的 HTML 寻找这个属性,注册表单的字段,只有到那时接收提交的端点才会存在。由此产生三个结果:

  • 网站必须托管并构建在 Netlify 上--检测发生在他们的构建流程里,而不是在浏览器里。
  • 那些在客户端动态渲染表单的框架(而不是直接输出已经带有该属性的静态标记)通常需要额外的变通方案,因为构建时的扫描器根本找不到可以识别的内容。
  • 表单能否存在取决于 Netlify 构建是否成功,而不是取决于标记本身。

这带来的锁定问题

这些都算不上真正的缺陷--对于一个想要提供集成功能的平台来说,这是合理的设计。但这意味着您的联系表单并不真正属于您的网站;它属于您的托管合同。迁移到 Vercel、Cloudflare Pages、一台普通 VPS,或者别的什么地方,表单就得按照另一套机制重新搭建。出于成本、性能或边缘功能考虑评估第二个托管平台时,表单会成为一个必须在迁移之前重新解决的问题项。一个联系表单能对基础设施决策施加这么大的影响力,实在有点奇怪。

与托管平台无关的替代方案

托管式表单后端不关心 HTML 是从哪里提供的,从而消除了这种耦合。这里没有构建时扫描,也没有需要依赖的平台集成--只是一个普通表单,其 action 指向一个端点:

<form action="https://formhook.app/f/fh_your-key" method="POST">
  <label>Email <input type="email" name="email" required></label>
  <label>Message <textarea name="message" required></textarea></label>
  <button type="submit">Send</button>
</form>

这段标记在 Netlify、Vercel、Cloudflare Pages、GitHub Pages,或者一台自己搭建的 VPS 上都能一模一样地工作--浏览器直接把 POST 请求发送到该端点,所以托管平台、构建工具或框架是什么都无关紧要。提交内容会出现在仪表盘中,触发推送通知,并转发到 webhook(Formhook 会自动识别 Discord、Slack 和 Microsoft Teams 的 URL,并为每一种格式化对应的负载;其他情况则会收到一个经 HMAC 签名的通用 JSON POST)。明年换个托管平台,表单也毫无察觉--action URL 是唯一把它和任何东西联系起来的因素,而它压根不和任何托管平台绑定。

垃圾内容的处理方式,不因托管平台而异

由于该端点在任何方面都不依赖托管平台,它必须自己处理垃圾内容,而不是借用某个平台的过滤能力:honeypot 字段会捕获那些填写了每一个输入框的机器人,速率限制会遏制滥发者,需要的网站还可以按表单添加可选的 Cloudflare Turnstile 验证(注重隐私,不是 Google reCAPTCHA)。这些都不取决于哪个平台在提供这个页面。

切换只需要一个属性

如果您已经在使用 Netlify 并且很满意,那么 Netlify Forms 完全没问题--对于从不打算离开的网站来说,这是一项合理的便利功能。但如果您正在迁移托管平台、比较不同平台,或者只是不想让一个联系表单成为您无法迁移的理由,一个与托管平台无关的后端就能彻底消除这个限制。Formhook 的免费层每月可处理 250 次提交,无需信用卡;表单接入只需一分钟,您的完整提交历史--包括上传的文件--随时都能导出为 ZIP。完整设置请参阅文档,或者免费开始,今天就把您现有的表单指向它。

一行代码上线可用的表单

欧盟托管,提交记录永久保存,所有套餐均支持推送通知。

免费开始

无需信用卡 · 阅读文档

继续阅读