跳转到内容
FFormhook
返回博客

博客

联系表单不工作?教你真正找出原因

· 1 分钟阅读

“我的联系表单不工作”通常意味着六种常见情况之一,靠猜测哪一种反而比逐一排查更浪费时间。正确做法是按可能性从高到低依次排查原因,先从最短时间内能提供最多信息的那一步开始:请求离开浏览器后到底发生了什么。

1. 检查请求到底做了什么

打开页面,打开开发者工具,切换到 Network 面板,自己提交一次表单。这里最常出问题的有两点:

  • action URL 有误--API 密钥输错、从旧表单复制过来但从未更新,或者(尴尬地常见)本地开发时的 localhost 一直没有切换成生产地址。
  • 请求发出去了,但返回了错误状态码。你不需要知道每个状态码的确切含义--只要是 4xx 或 5xx 响应,就足以说明问题出在接收端,而不是你的 HTML 里。

如果请求根本没发出去,或者发到了一个明显不是你表单后端的域名,这就是问题所在--不到一分钟就能找到,无需再去别处排查。

2. 确认它确实是以 POST 方式发送

没有显式设置 method="POST"<form> 默认使用 GET,会把字段以查询字符串的形式附加到 URL 上,而不是发送请求体--表单后端接口通常不会把它当作一次真正的提交来接受。先检查标签本身。

如果表单是通过 JavaScript 而不是浏览器原生 POST 提交的,更常见的问题是处理函数调用了 e.preventDefault() 来阻止默认导航,之后却实际上什么都没发送出去--一个坏掉的 fetch 调用、处理函数里端点写错,或是一次静默的提前 return。对访客来说,一个没有真正请求支撑的 preventDefault() 和一个失效的表单没有任何区别:页面就是……什么都不做。

3. 排查控制台,而不只是网络面板

对于任何基于 fetch 的提交,除了 Network 面板之外还要打开 Console 面板。CORS 错误、被拦截的混合内容请求(从 https:// 页面向 http:// 提交)、或提交处理函数中未捕获的异常,都会彻底中止请求--而这些都不会给访客产生任何可见的错误提示。它们看起来就是一片沉默,而这正是一个坏掉的表单从外部看起来的样子。

4. 检查通知到底去了哪里

如果第 1 步中的请求返回了成功状态,说明提交确实到达了后端--剩下的问题只是提醒去了哪里。先检查垃圾邮件和推广邮件文件夹;这是“丢失”的通知其实并没有真正丢失的最常见原因。如果你使用自定义的已验证域名而不是默认发件人发送邮件,SPF 或 DKIM 配置错误会导致邮件被接收方邮件服务器静默过滤或退回,从你这边看,这和“根本没发出去”一模一样。

5. 考虑被静默拒绝的情况--速率限制和失效的 honeypot

合法提交偶尔也会被当作可疑请求处理。调试时从同一个 IP 反复快速测试,正好符合速率限制想要拦截的模式,即使没有任何恶意也可能触发它。在断定“东西坏了”之前,先等几分钟再试一次。

一个更隐蔽、也真的很常见的 bug:honeypot 字段。大多数垃圾信息防护都包含一个真实访客既看不到也不会填写的隐藏字段--如果机器人填写了它,该次提交就会被静默丢弃。一次 CSS 回归(某个类名被重命名、某个样式表加载失败、某次布局改动意外“取消隐藏”了错误的元素)可能让这个字段对真实用户变得可见,用户要么被这个多出来的字段搞糊涂,要么更糟--被密码管理器自动填充了它,从而触发了原本针对机器人的同一个过滤器。如果提交是在一次改版或 CSS 改动之后才开始失败的,这是首先值得检查的地方。

检查仪表盘,而不只是收件箱

贯穿以上所有内容的核心教训是:“我收到邮件了吗”和“提交到达了吗”并不是同一个问题,把两者混为一谈正是这类 bug 需要花几天而不是几分钟才能查清的原因。使用 Formhook 时,任何真正到达后端的提交都会出现在仪表盘中,无论通知邮件是否成功送达--所以在以上所有步骤之前,最先该做的有用检查其实就是登录进去看一眼。如果它在那里,问题出在通知这一侧(第 4-5 步)。如果不在,问题出在更上游,请求甚至都没到达后端(第 1-3 步)。

值得定期做,而不只是出问题时才做:上线前测试检查清单介绍了那套十五分钟的流程,能在真实访客遇到之前拦下大部分此类问题。如果你正在评估某个表单后端,想知道一个正常运作的系统从头到尾是什么样子,文档定价页面介绍了配置方法和免费层级。

一行代码上线可用的表单

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

免费开始

无需信用卡 · 阅读文档

继续阅读