上周有个外贸站找过来:前台 Contact Form 7 一直显示「谢谢,消息已发送」,老板却说「半个月一条询盘都没有」。后台一打开,插件自己的提交记录里其实有十几条------问题不在「表单坏了」,而在通知邮件根本没走出主机,再加上页面缓存把带 nonce 的 AJAX 偶发搞挂,访客侧偶发 403,线索就这样静悄悄丢了。
这类故障最烦的是「看起来成功」。下面按我平时的顺序拆:先分清提交成功还是投递失败,再查 SMTP / DNS,再看反垃圾误伤,最后才动缓存与 CDN。默认你有备份,改 SMTP、缓存规则前先记一笔,方便回滚。
结论先放这
- 前台「发送成功」≠ 邮件到达。先看表单插件是否落库/有提交记录,再查发信。
- PHP
mail()在多数虚拟主机上不可靠;优先 SMTP,发件人用本域邮箱,访客邮箱放 Reply-To。 - SPF / DKIM / DMARC 配错或配多条,常见表现是进垃圾箱或被拒收,而不是表单报错。
- 页面缓存 / CDN 误缓存表单页或 AJAX,会出现偶发失败、重复提交、nonce 过期------和「邮件收不到」是另一条线,别混着改。
适用场景
- Contact Form 7、WPForms、Fluent Forms、Gravity 等常见表单;企业站 / 外贸询盘为主。
- 能进后台、能看主机邮件日志或至少能装 SMTP 插件;最好有 staging。
- 已开页面缓存或 CDN 的站点,务必把「缓存冲突」单独列一条假设。
一、先定性:提交链路 vs 投递链路
打开表单插件的「提交记录 / Entries」(没有就临时开一周日志),做一次真实提交:
| 现象 | 更可能在哪一层 |
|---|---|
| 前台失败 / 红字 / 转圈不停 | 前端 JS、nonce、REST/AJAX、缓存拦请求 |
| 前台成功,后台无记录 | 提交未进 PHP,或写库失败 |
| 后台有记录,邮箱无信 | SMTP / 主机发信 / DNS 认证 / 收件方过滤 |
| 偶发成功偶发失败 | 缓存、WAF、限流、邮件服务商配额 |
预期:你能用一句话说清「是没提交进去,还是提交进去了但信没到」。后面只动对应那一层。
二、通知配置:先排除「设错了」
在表单的邮件/通知面板核对:
- 收件人是否写对、通知是否启用;抄送/密送不要指向已停用的邮箱。
- From 用本站域名邮箱 (如
noreply@你的域名),不要把访客填的邮箱当 From------很多服务商会直接拒或进垃圾箱。访客地址放 Reply-To。 - Contact Form 7 保存时若顶部有警告(发件域不匹配等),先消掉再测。
用插件自带的「发送测试」或再提交一条带明显标题的测试单,方便在收件箱/垃圾箱搜索。
三、SMTP:把「能不能发出去」变成可观测
很多主机上 mail() 返回 true,信却进不了公网。更稳的做法是走 SMTP(企业邮、域名邮或事务邮件服务),用 WP Mail SMTP / FluentSMTP 一类插件填服务器、端口、加密与账号。
改完后建议在主题或临时 mu-plugin 里不要长期开调试;需要时用插件的测试页,或短时打开 WordPress 调试邮件日志(测完关掉)。
bash
# 仅示意:在能 SSH 的机器上看本机是否还能直接投递(多数共享主机无权限或结果无意义)
# 真正验收以「测试信到达收件箱/垃圾箱」为准
配置注意:
- 465 / 587 与 SSL/TLS 别混用;账号开了「应用专用密码」的,别继续用网页登录密码。
- 生产改 SMTP 前记下旧配置;测通前不要关掉原来还能用的通道(若有)。
- 回滚点:插件切换回「默认 PHP mail」或还原上一组 SMTP 字段即可;DNS 记录另说。
四、DNS:SPF / DKIM / DMARC 三件套
信「发出去了」但仍进垃圾箱或被拒,优先查域名 DNS:
- SPF :一个域名只应有一条 SPF TXT;多条常直接校验失败。把实际发信服务商的
include:写进这一条。 - DKIM:按邮件服务商后台给的选择器与公钥加 TXT;改完用服务商或在线检查工具验一次。
- DMARC :可先
p=none观察,再逐步收紧;没有报告也别一上来p=reject。
改 DNS 要等 TTL;预期是测试信的「原始邮件头」里 SPF/DKIM 显示 pass。不要只看「感觉进收件箱了」就结案。
五、反垃圾与误伤
Akismet、表单自带 honeypot、reCAPTCHA/Turnstile、防火墙规则,都可能让「真人提交」直接消失或标成垃圾:
- 后台垃圾/拦截列表里搜测试关键词;
- 短时关掉验证码或放宽规则做 A/B(staging 优先);
- WAF / 主机防火墙若拦
admin-ajax.php、/wp-json/,表单 AJAX 会表现为转圈或 403。
预期:同一网络下连续 3 次真人提交都进「有效条目」,而不是进垃圾箱或完全无记录。
六、和缓存 / CDN 打架的那几类
表单页、预览页、带 nonce 的 REST/AJAX,被页面缓存或边缘 HTML 缓存后,典型症状是:
- 偶发「发送失败」、刷新后又能发;
- 多人共用同一缓存页上的过期 nonce;
- 提交进了旧的 action URL。
处理原则(不绑定某一家插件名):
- 表单所在 URL、预览、带
admin-ajax/ 相关 REST 路径:绕过页面缓存,或提交接口强制动态。 - CDN 缓存键不要把无关营销 Cookie 和会话 Cookie 搅在一起;登录态、带表单的动态页优先回源。
- 改完规则后用无痕窗口 + 第二次提交验收,并清一次相关 URL 的源站与边缘缓存。
缓存键、Cookie 与回源怎么对齐,可对照这篇写得更细的说明:WordPress CDN 与缓存回源要点。
回滚点:恢复「表单 URL 不缓存」的旧规则;清掉该 URL 的脏缓存后再测。
七、验证清单(建议原样抄进工单)
- 测试提交在后台有对应记录(时间、字段对得上)
- 通知邮件到达目标收件箱(含垃圾箱排查记录)
- 邮件头 SPF/DKIM 为 pass(若已配)
- 无痕窗口连续提交 2--3 次均成功,无 403/nonce 报错
- 若有 CRM/表格同步,目标表新增一行且字段未错位
- 缓存/CDN 规则变更已记文档,出问题可回滚
常见坑
- 只看前台绿字,从不打开 Entries / 邮件头;
- From 写成访客邮箱,收件方直接拒;
- 同一域名堆了两条 SPF;
- 为了「加速」把整站 HTML 长缓存,表单页一起进去;
- 生产同时开关多个安全/验证码插件,失败时不知道是谁拦的。
延伸阅读
若需要按你的网址把表单、通知、缓存与插件冲突排个优先级清单,可走站点诊断页:WordPress 站点诊断与问题优先级。
(实操笔记;以你站实测与备份条件为准,不承诺投递率或搜索排名。)