表单提交成功却收不到信,多半是SMTP端口被封

来源:互联网 时间:2026-10-29

表单点提交,前端提示发送成功,收件箱里干干净净。垃圾箱翻过,也没有。这种情况最难受,用户以为信已经发出去了,隔天客户来信问,才发现一封都没到。

PHP的mail()返回值只代表交给了本机的sendmail,不代表对方收到了。sendmail再往上游递,上游收不收、退不退,mail()一概不知道。前端那个成功,说到底只是代码没报错。有人在mail()后面加了个if判断返回值,成功就提示,这个判断只能证明sendmail进程起来了。

你得先确认走的是哪条路。php -i里找sendmail_path,指向/usr/sbin/sendmail就是用本机MTA,指向别的东西或者空着,就是走SMTP扩展。两条路的排查方向完全不同,别混着查。sendmail_path指向一个转发脚本的情况也有,那种是脚本在发信,日志要去脚本自己的输出里找。

本机MTA的话,看/var/log/maillog或者/var/log/mail.log。里面有queue id、收件人、状态。状态是deferred,说明在反复重试,原因写在后面,connection timed out最常见。这类原因几乎只有一个:25端口出向被封。腾讯云、阿里云、华为云的新机器默认封25,要提工单申请,通过率也不高。deferred会一直重试,周期是分钟级,最长撑五天,五天后放弃并回一封退信,那封信通常发给webmaster,没人看。

nc -zv smtp.exmail.qq.com 25试一下,卡住不动就是被封。同一台机器再试465和587,能通就直接换端口。25通、465不通,是防火墙只放了一半,一样要提工单。

换端口要改发信方式。25是明文,465是SSL,587是STARTTLS。mail()不支持后两个,得换成PHPMailer或者Symfony Mailer这类库,配上SMTP主机、端口、账号密码。库里的加密方式要跟端口对上,587配ssl一样连不上。换库之后把mail()的调用点全找出来,有的框架封装在helper里,光搜函数名搜不全。

用第三方SMTP还有个坑:发件人地址必须和认证账号同域,不然对方按伪造处理。腾讯企业邮要求From和登录账号一致,不一致直接拒。代码里写死一个别的域名的发件人,测试的时候能过,上线之后全退。现在多数服务商还要求From和信封发件人都落在认证域上,光改显示名没用。同一封测试信,企业邮能到、自建SMTP到不了,问题就在发信域的认证上,不在内容。

还有一种情况是信发出去了,只是进了垃圾箱。那是SPF和DKIM的问题,跟端口无关,两边的现象看起来一样,查的路径完全不同。先分清是哪一类,能省掉一半无用功。

改完给自己发一封,打开原始邮件看Received头。每一跳的时间和处理它的服务器都记在里面,哪一跳之后没了,问题就在那一跳。Received头要从下往上看,最下面那条是发信服务器写的,最上面一条是收件服务器写的。

相关文章

标签:

A5创业网 版权所有