做产品验证、跑自动化回归、批量试用各种只打算用一次的工具,最烦的往往不是填表单,而是填完表单之后的那三个月。各种营销邮件、产品更新通知,还有来路不明的推广,会持续堆积在一个你根本不想打理的信箱里。免费临时邮箱这类东西之所以一直有稳定需求,本质上就是在解决这件事:用一个随时可以丢弃的地址,换一次性的验证通过,用完即弃,不留下长期留痕。而它背后真正值钱的部分,是个人隐私保护:把“我的长期身份锚点”和“一次性的注册行为”在物理上隔开。
内容分成这几块。第一块讲清楚临时邮箱到底解决什么问题、有哪几种形态,以及哪些场景用了会出事;第二块从 DNS 和收信链路往下拆,解释验证码为什么会慢半拍、邮件为什么会被回收;第三块是动手环节,我会给一套能跑起来的自建收件箱方案,包括域名规划、收信服务、入库和清理;第四块讲选型,给出五个硬指标和一张对照表;第五块专门讲隐私保护的边界,也就是临时邮箱做不到的事;最后是排查速查表。适合三类人看:经常要试用各种服务的产品、运营或测试岗,需要验证注册邮件的开发者,以及单纯不想让主邮箱到处留痕的普通用户。基础一般的读者看第一、四、六部分就够用,想自己搭的从第二部分开始。
1. 先把“临时邮箱”这件事说清楚
1.1 它真正解决的三个痛点,跟“免费”关系不大
很多人以为临时邮箱的核心卖点是免费,其实不是。免费只是降低了尝试门槛,真正支撑它存在的是三件事。
第一件,邮箱地址在现代互联网里已经变成了身份锚点。你可能没意识到,一个邮箱地址能关联出多少东西:注册过的所有平台、订阅记录、支付账户、社交关系、甚至部分平台的历史头像和昵称。多数人在几十个站点上复用同一个邮箱,任何一个站点的数据泄漏,都会让这个邮箱变成一张能拼出你大部分网络行为的索引卡。临时邮箱的价值,是把这张索引卡切断。
第二件,营销触达与数据流转不可控。你为了下载一份资料填了邮箱,接下来会发生什么,你完全没有控制权。轻则每周一封推送,重则地址进入流转环节,被不同来源反复触达。这不是危言耸听,是行业里长期存在的现实。
第三件,大量注册行为本质上是“一次性验证需求”。你只是想看看某个后台长什么样,只是想确认一封验证邮件的排版对不对,只是想下个白皮书。这类需求的特征是:验证通过之后,这个地址的使命就结束了。用一个长期地址去承接一次性需求,本身就是资源错配。
我见过不少团队的做法是养一个“杂项邮箱”,所有不重要的事情都往那儿丢。这招比复用主邮箱好一点,但仍然是一个长期存在的、被反复暴露的地址,而且时间一长,邮箱里什么都有,根本没法做归类和清理。临时邮箱的思路更彻底:不是“集中”,而是“隔离 + 到期销毁”。
注意:这里说的“隔离”是指用途隔离,不是身份隐匿。临时邮箱不改变你是谁,它只是把某个一次性行为和你长期使用的地址分开。这两件事经常被混为一谈,后面第五部分会专门讲。
1.2 四种形态,能力边界差别很大
市面上叫“临时邮箱”的东西,形态差别其实相当大。按实现方式分,我一般归成四类,你在选用的时候最好先确认自己碰到的是哪一类。
第一类是网页即用型,打开页面就给你一个随机地址,不需要注册。这类通常十分钟到一小时不等,地址过期就作废,页面会自动刷新收件箱。特点是零门槛,缺点是地址是系统分配的,你没法指定,也没法在多个设备之间同步查看。
第二类是可自定义前缀型。同样是打开即用,但允许你手填一个前缀,比如你填一个跟自己项目相关的词,就得到你填的词@某临时域这样的地址。这类在开发和测试场景里明显更好用,因为你可以按用途分配不同前缀,一会儿测注册流程、一会儿测密码重置,收件箱里不会全混在一起。
第三类是开放接口型。提供 HTTP 接口,返回域名列表、生成地址、拉取信件,全部走 JSON。这类东西本身不是给人看的,是给脚本用的。做自动化测试的团队最需要的其实是这一类,因为它能被塞进 CI 流程里。
第四类是自建型。自己有一个域名,配好收信记录,写个收信服务,想怎么存怎么存,想保留多久保留多久。门槛最高,但可控性也是最高的,尤其是当你有合规要求、不能把邮件内容发给第三方的时候,基本只有这条路。
| 形态 | 地址可控 | 适合人群 | 主要短板 |
|---|---|---|---|
| 网页即用型 | 否,系统随机分配 | 偶发一次注册 | 无法指定前缀,多设备不同步 |
| 自定义前缀型 | 是,可手填 | 测试、运营、多任务并行 | 公共域名容易被部分站点拦截 |
| 开放接口型 | 通过接口指定 | 开发、自动化测试 | 需要写代码,不适合手动操作 |
| 自建型 | 完全可控 | 团队、有合规要求者 | 要维护域名和收信服务 |
1.3 哪些场景能用,哪些场景用了会给自己添麻烦
这部分我建议你认真看一下,因为踩坑的人基本都栽在这儿。
可以放心用的场景:下载一份公开资料、订阅一份不确定要不要长期看的资讯、试用一个不涉及资金的后台系统、给论坛提一个一次性问题、测试自家产品的注册邮件模板和验证码流程、验证密码重置链接的跳转是否正确、做邮件排版兼容性检查。这些场景的共同点很明确——没有资金、没有长期凭证、没有需要找回的账号。
绝对不该用的场景,我列几条最典型的:
- 任何跟资金有关的账户。绑卡、充值、提现,一旦需要找回,临时地址已经销毁了,你连验证码都收不到。
- 需要长期维护的账号。云服务、代码托管、域名管理这类,找不回密码的代价可能是一次事故。
- 接收合同、发票、法律文书的地址。这些内容有留存要求,临时邮箱的销毁策略和留存要求是直接冲突的。
- 涉及实名或资质认证的注册。这类注册本身就要求真实可追溯的联络方式,用一次性地址属于给自己制造后续麻烦。
- 工作沟通。这个不用解释。
提示:判断标准其实只有一句话——这个账号三个月后还需要你登进去吗?如果答案是“需要”,就别用临时地址。如果答案是“大概率不用”,那用它就是合理的。
还有一条边界要说清楚:临时邮箱是用来保护自己隐私的工具,不是用来批量注册、绕过平台规则、规避正常审核的工具。后者不但违反多数平台的服务条款,而且从技术上也走不通——现在主流平台对一次性域名邮箱的识别已经相当成熟,你费半天劲,最后卡在验证环节,白折腾。
2. 技术拆解:一封邮件是怎么“临时”起来的
2.1 从 DNS 开始:MX 记录决定了邮件往哪儿走
临时邮箱看起来是个网页,本质上是一个能接收任意收件人的邮件服务器 + 一个按地址查询的展示界面。整条链路的第一环不是代码,是 DNS。
别人往任意前缀@你的临时域发信时,发信方的邮件服务器会先查这个域的 MX 记录,找到负责收信的服务器地址,然后把邮件投递过去。所以要自建,第一步是配好这几条记录。
| 记录类型 | 主机名示例 | 填写内容 | 作用说明 |
|---|---|---|---|
| MX | @(根域) | 10 mail.your-domain.com | 指定收信服务器,数字是优先级,越小越优先 |
| A | mail.your-domain.com | 指向你的服务器地址 | 让 MX 指向的主机名能被解析 |
| SPF | @ | v=spf1 -all | 声明本域不对外发信,降低被冒名发信的风险 |
| DMARC | _dmarc | v=DMARC1; p=reject; | 配合上一条,进一步收紧策略 |
这里有两个细节值得单独说。
第一,收信服务器必须开“接受任意收件人”。默认情况下 MTA 遇到不存在的收件人会拒收,但临时邮箱的业务逻辑恰恰相反——任何前缀都得收下来。这个模式在邮件系统里叫 catch-all,配置时要在收信服务端放行,而不是在 DNS 层面做什么特殊处理。很多人卡在这一步,误以为是 DNS 没生效,其实 DNS 早就好了,是服务端把信给拒了。
第二,SPF 写-all而不是留空,是有意为之。临时邮箱域只收不发,如果有人拿这个域去冒名发信,-all配合p=reject能让对方收信方直接拒绝。这不是安全上的必需品,但是个成本极低的好习惯。我见过一些自建临时邮箱域因为没配这两条,后来被拿去做退信伪造,域名信誉掉得很快,最后连正常收信都受影响。
2.2 收信链路:为什么验证码有时会慢半拍
一封邮件从发出到出现在你眼前的页面上,中间至少经过四跳:发信方服务器、你的 MX 服务器、你的入库逻辑、前端刷新。任何一跳有延迟,你看到的都是“怎么还不来”。
各大平台发验证邮件的策略差别很大。有的发信即投递,几秒钟就到;有的一开始走队列,高峰期限流,可能压十几秒到几十秒;还有的会对新域名做信誉观察,第一次投递尝试失败会等一段时间重试。这就是为什么同一套临时邮箱,收某个平台的验证码很快,收另一个平台的就慢。
入库逻辑的延迟通常是自己造成的。常见写法是收信时同步写数据库、同步做正则会员解析、同步做附件处理,一封信处理两百毫秒,赶上并发就排队了。稳妥的做法是收信端只做最轻的动作——把原始邮件落盘或塞进队列,立刻返回成功,后续解析异步做。邮件协议本身对响应时间有要求,收信端处理太慢,发信方会判定投递失败并重试,表现出来就是你在页面上看到好几封重复邮件。
前端刷新的延迟是最容易被忽略的。早期很多人用固定间隔轮询,三秒一次,看着还行。但用户量一上来,轮询请求会把后端打满,于是只能把间隔调大,体验就变差了。后来普遍换成带退避的轮询或者服务端推送。轮询的间隔设计有个经验值:前 60 秒用 2 秒间隔,60 秒到 180 秒用 5 秒,之后用 10 秒。理由是绝大多数验证邮件在 60 秒内到达,前期高频能显著改善体感,后期降频能省下大量请求。
2.3 邮件生命周期的三种回收策略
“临时”这个词落到实现上,就是三种回收策略的组合。
按时间回收是最常见的,地址生成后给一个 TTL,比如 10 分钟、1 小时、24 小时,到期后地址失效、信件删除。关键在于过期判断要在读取时也做一次,不能只依赖定时任务。我见过只靠定时任务清理的实现,任务挂掉半天,页面上还能翻到十几个小时前的信件,这是明确的隐私问题。
按容量回收是补充手段。即便没到期,单个收件箱超过 50 封或者 5MB,也应该滚动删除最旧的。这么做的原因很实际:临时邮箱是公开可访问的,没有任何身份校验,一个地址被反复投递大附件,很容易把存储打满。
按内容类型回收是最容易被忽视但最重要的一条。我的建议是只保留纯文本正文和必要的头部字段,附件一律不入库。原因有两层:一是存储成本,附件通常是正文的几十倍;二是风险,附件是不可信输入,一个公开可访问、允许任意人投递附件的系统,等于给自己开了一个文件上传入口。真要保留附件,至少要做类型白名单、大小上限、独立存储域,成本会翻好几倍,而临时邮箱这个场景根本不需要。
3. 动手:搭一套自己能用的临时收件箱
这部分给一套最小可用方案。目标很明确:一个域名、一台小机器、一个收信服务、一个页面,能收任意前缀的邮件,能在页面上看到,到期自动清。以下参数是基于常见实践的合理取值,你可以按自己的量级调整。
3.1 域名与子域规划
不要拿主域做临时邮箱。这是我最想强调的一条。临时邮箱域的信誉天然偏低,一旦被大量站点拉黑,同域下的正常业务邮件也会受牵连。正确做法是单独注册一个便宜域名,或者用主域的一个独立子域,跟业务域彻底分开。
推荐的结构是这样:
- 根域
your-temp-domain.com只放 MX 和 SPF/DMARC,不挂任何网站。 mail.your-temp-domain.com指向收信服务器。- 收信服务监听 25 端口,接受任意收件人。
如果量级上来了,还可以准备两到三个备用域轮换。原因很直接:某些站点会维护一次性邮箱域名清单,一个域用久了命中率就上去了。多域轮换不是为了对抗谁,是为了在正常使用范围内保持可用性。
存储估算这件事提前算一下,能省很多麻烦。假设日均收信 5000 封,只存纯文本、单封平均 12KB,那么一天的数据量约 60MB。TTL 设 24 小时,峰值存储就是 60MB 左右;设 72 小时就是 180MB。这个量级用 SQLite 完全够,不需要上任何分布式存储。反过来说,如果你把附件也存进去,单封平均可能变成 300KB,一天就是 1.5GB,成本立刻上一个量级,而且清理逻辑也更复杂。
3.2 收信服务:一个够用的最小实现
下面这段是用 Python 写的最小收信端,核心逻辑是收下任意收件人的邮件、解析出正文、按收件箱入库。实际部署时记得放到反向代理后面,25 端口只对公网开放收信,管理接口不要暴露。
import asyncio import sqlite3 import time from email import message_from_bytes from email.header import decode_header from aiosmtpd.controller import Controller DB = "inbox.db" TTL_SECONDS = 24 * 3600 MAX_PER_BOX = 50 def init_db(): conn = sqlite3.connect(DB) conn.execute(""" CREATE TABLE IF NOT EXISTS mails( id INTEGER PRIMARY KEY AUTOINCREMENT, box TEXT NOT NULL, sender TEXT, subject TEXT, body TEXT, created_at INTEGER ) """) conn.execute("CREATE INDEX IF NOT EXISTS idx_box ON mails(box, created_at)") conn.commit() conn.close() def safe_header(raw): if not raw: return "" parts = decode_header(raw) out = [] for text, enc in parts: if isinstance(text, bytes): out.append(text.decode(enc or "utf-8", errors="replace")) else: out.append(text) return "".join(out) def pick_body(msg): # 只取纯文本,附件和 HTML 一律丢弃 if msg.is_multipart(): for part in msg.walk(): if part.get_content_type() == "text/plain" and not part.get_filename(): payload = part.get_payload(decode=True) or b"" return payload.decode(part.get_content_charset() or "utf-8", errors="replace") return "" payload = msg.get_payload(decode=True) or b"" return payload.decode(msg.get_content_charset() or "utf-8", errors="replace") class Handler: async def handle_DATA(self, server, session, envelope): # catch-all:收下任意收件人 rcpt = envelope.rcpt_tos[0].lower() box = rcpt.split("@")[0] msg = message_from_bytes(envelope.content) now = int(time.time()) conn = sqlite3.connect(DB) conn.execute( "INSERT INTO mails(box, sender, subject, body, created_at) VALUES (?,?,?,?,?)", (box, safe_header(msg.get("From")), safe_header(msg.get("Subject")), pick_body(msg)[:20000], now) ) # 单箱容量回收 conn.execute(""" DELETE FROM mails WHERE box = ? AND id NOT IN ( SELECT id FROM mails WHERE box = ? ORDER BY created_at DESC LIMIT ? ) """, (box, box, MAX_PER_BOX)) conn.commit() conn.close() return "250 Message accepted for delivery" if __name__ == "__main__": init_db() controller = Controller(Handler(), hostname="0.0.0.0", port=25) controller.start() asyncio.get_event_loop().run_forever()几个实现上的取舍说明一下。
收信端不做正则会员提取。很多人想一步到位,收信时就把验证码抽出来。不建议这么干,因为邮件格式千奇百怪,抽错了反而误导用户。更稳的做法是保留全文,前端用一段正则做高亮,抽不到就让人自己看。
正文截断到 20000 字符。这是防滥用的底线,有人会往临时地址投递超大正文。截断之后单封上限就锁死了,存储估算才有意义。
返回 250 而不是其他状态码。邮件协议里 250 表示接受投递,返回别的会让发信方重试,会造成重复投递。
3.3 清理任务与过期判断
清理分两层,前面提过:读的时候判断一次,定时任务再兜底一次。只靠定时任务是很多实现出隐私事故的根源。
def purge_expired(): deadline = int(time.time()) - TTL_SECONDS conn = sqlite3.connect(DB) conn.execute("DELETE FROM mails WHERE created_at < ?", (deadline,)) conn.commit() conn.close()这个函数挂到 crontab 上,五分钟跑一次就够。DELETE之后记得定期执行一次VACUUM,否则 SQLite 文件只会涨不会缩,磁盘占用看着很吓人。
读取接口里也要带上时间条件,别只查 box:
SELECT id, sender, subject, body, created_at FROM mails WHERE box = ? AND created_at >= ? ORDER BY created_at DESC LIMIT 20;这样即便定时任务挂了,过期信件也不会被读出来。
3.4 前端:带退避的轮询怎么写
前端这块最容易被写糙。固定间隔轮询在用户少的时候没问题,稍微有点量就会把后端压住。下面这个带退避的版本,逻辑简单但够用。
const box = new URLSearchParams(location.search).get("box"); let elapsed = 0; let timer = null; async function fetchMails() { const res = await fetch(`/api/mails?box=${encodeURIComponent(box)}`); if (!res.ok) throw new Error("fetch failed"); const list = await res.json(); render(list); // 有新信件就重置节奏 if (list.length > 0) elapsed = 0; } function nextInterval() { if (elapsed < 60) return 2000; if (elapsed < 180) return 5000; return 10000; } async function loop() { try { await fetchMails(); } catch (e) { // 出错不要停,拉长间隔继续 } const wait = nextInterval(); elapsed += wait / 1000; timer = setTimeout(loop, wait); } loop();这个写法有两个细节。一是有新信时把elapsed归零,重新回到 2 秒节奏,因为用户这时候大概率在等验证码,体验优先。二是出错不中断循环,只拉长间隔,页面不会卡死在错误状态。
提示:页面 URL 里带
box参数意味着这个收件箱是公开可访问的。这是临时邮箱的固有特性,也意味着任何人都能看到这个地址收到的邮件。所以临时邮箱只能收“用完就没价值”的内容,任何带个人信息的邮件都不要往里投。这一点在第五部分还会再说。
4. 选型:怎么判断一个临时邮箱靠不靠谱
4.1 五个硬指标,按重要性排序
选现成服务的时候,别只看页面好不好看。我一般按这五个指标过一遍。
第一,可用率与延迟。这个最直接,但要看的是“典型延迟”而不是“最快延迟”。很多服务演示的时候秒到,实际用起来经常几十秒。判断方法很简单:连续测五个不同平台的注册邮件,记录到达时间,看中位数,别只看最快的那次。
第二,是否允许自定义前缀。这一点对测试场景几乎是决定性的。不能自定义前缀,你同时测三个流程,收件箱里全是混的,得靠肉眼从一堆邮件里找。
第三,日志与留存策略。这个最不透明,也最影响隐私。你投进去的邮件,对方存多久、存不存发信方 IP、会不会用于其他目的,绝大多数服务不会明说。我的判断方式是:看它页面有没有公开说明、有没有隐私条款、域名注册信息是否清晰。什么都查不到的服务,把它当成“公开广播”来理解比较稳妥。
第四,域名信誉。有些一次性域名被大量站点加入了拦截清单,你填上去直接提示“不支持该邮箱”。这个没法提前查,只能试。经验是一线服务通常有几个备用域,页面会提示你换一个试试,愿意做这个功能说明维护方是真的在运营。
第五,附件与 HTML 的处理。如果你只是收验证码,纯文本就够了,附件支不支持无所谓。但如果你要测邮件模板的渲染效果,HTML 就必须保留。这一点在选型时经常被忽略,等到要看排版了才发现对方只给你看纯文本。
4.2 一张对照表,把判断标准落下来
| 判断维度 | 及格线 | 优秀表现 | 踩雷信号 |
|---|---|---|---|
| 到达延迟 | 中位数 10 秒内 | 5 秒内,且波动小 | 演示秒到,实测半分钟以上 |
| 前缀控制 | 支持手填 | 支持按前缀分组查看 | 只能系统随机分配 |
| 留存说明 | 页面上有基本说明 | 有完整条款与到期规则 | 什么都查不到 |
| 域名轮换 | 有备用域 | 页面提示当前域可用性 | 单一域,被拦后无替代 |
| 内容保留 | 保留纯文本 | 可选保留 HTML 便于测排版 | 强制剥离,连链接都看不到 |
| 界面干扰 | 少量广告 | 清爽无弹窗 | 大量弹窗、诱导点击 |
这张表不用全打勾,按你的用途排优先级。如果是纯收验证码,前两行最关键;如果是测邮件模板,最后一行不能将就。
4.3 三个我踩过的坑
坑一:公共收件箱被人看过。早期我用某类网页即用型服务,图省事一直是同一个页面刷新。后来才意识到,那个地址是系统分配的,跟我同时拿到的可能有别人,虽然概率低,但机制上不排他。从那以后,凡是涉及任何一丁点信息的注册,我都先看这个地址是不是可自定义前缀的。
坑二:域名被拉黑,白忙半小时。有一次给一个平台做注册流程测试,连着换了两个临时域都被拦。当时以为是代码问题,查了半小时才发现是域名进了拦截清单。这个教训是:注册流程测试一定要准备两到三个备用域,被拦了立刻换,别在同一个域上反复试,越试越像异常行为。
坑三:服务突然关停,历史记录全没了。这类免费服务,关停是没有预告的。我现在的做法是,凡是测试过程中需要留档的邮件(比如客户确认过的邮件模板截图),一律在当天导出到自己的文档里,不依赖任何第三方保存。临时邮箱是“临时”的,把长期资料放在上面本身就不合理。
5. 隐私保护的边界:临时邮箱做不到的事
5.1 它隔开的是地址,不是身份
这是最需要说清楚的一点。很多人对临时邮箱有一个误解,觉得用了它就“隐身”了。不是的。临时邮箱做的事情非常具体:把一个一次性注册行为和一个长期邮箱地址切开。它不改变你的网络出口、不改变你的设备特征、不改变你填的其他信息。
举个具体的例子。你在某个站点用临时邮箱注册,填了昵称、选择了一个比较特殊的兴趣标签、用了跟其他平台一样的用户名。那么即便邮箱是一次性的,这几项信息叠在一起,照样能把这次注册跟你其他账户关联起来。邮箱只是众多关联维度里最简单的一个,去掉它确实降低了关联度,但不是全部。
所以真正有效的用法是组合:一次性地址 + 不重复的用户名 + 不填可选的个人信息 + 不绑定任何已有账号。只做第一步,效果有限。
5.2 邮件正文本身也会泄漏信息
第二个容易被忽略的点是邮件内容。你以为收进来的是验证码,实际上邮件头部带着不少东西:发信时间、发信服务器、邮件经过的中转节点、有时候还有你注册时用的设备信息被写进模板里。
而临时邮箱的收件箱是公开可访问的。也就是说,任何拿到这个地址的人,都能看到这些内容。所以在使用上有一条硬规矩:只接收验证码、激活链接、通知类邮件,绝不接收账单、身份证明、地址确认这类内容。
还有一点,很多人习惯在不同平台用同一个临时地址反复注册。这等于自己把关联关系又建回来了。更稳妥的做法是按用途分配前缀,用完一个丢一个,不要跨平台复用。
5.3 几条必须守住的使用红线
工具本身没有立场,用法有。我整理了几条自己一直守着的规矩。
不用于批量注册或绕过平台规则。这条前面提过,再从技术角度说一次:主流平台对一次性邮箱的识别已经很成熟,MX 记录、域名清单、行为模式都能用来判断,你花时间对抗,产出比极低。而且这类行为通常违反服务条款,账号随时可能被处理,折腾一圈什么也留不下。
不接收任何需要留存的凭证。合同、发票、订单确认、保修凭证,这些都有留存要求,而临时邮箱的销毁策略跟留存要求是直接冲突的。这类内容用有长期归档的邮箱接收,这是基本常识。
不在需要实名的场景里使用。涉及资质认证、实名核验的注册,本身要求联络方式真实可追溯,用一次性地址只会给自己制造后续核验的麻烦。
不用它做任何需要事后追责的事。这个不用展开,但值得提一句:临时邮箱的设计目标就是“不可追溯”,你把需要追溯的沟通放在上面,等于主动放弃了证据链。
6. 常见问题与排查速查
6.1 收不到信,按这个顺序查
收不到信是最常见的问题,原因分布其实很集中。按下面这个顺序查,能覆盖八成情况。
第一步,先确认域名解析生效了没。在你自己的机器上查一次 MX 记录,看返回的是不是你配置的那台服务器。注意 DNS 有缓存,刚配完可能要等一会儿,别急着改配置。
第二步,确认收信服务是不是把信拒了。这是自建场景最高频的原因。日志里如果出现“不存在的收件人”“中继被拒绝”这类字样,基本可以确定是 catch-all 没开。检查收信服务的本地收件人校验逻辑,把它关掉或者配成全通过。
第三步,看发信方那边有没有退信。如果是你自己在测自家产品,去看发信日志,有没有投递失败、被限流、被对方拒收。很多时候信根本没发出来,问题不在接收端。
第四步,确认是不是平台直接拦了域名。表现出来是“提交后提示邮箱不可用”,压根没到发信环节。这种情况换域,别在同一个域上反复试。
第五步,检查前端刷新。如果后台库里已经有信,页面上没显示,那是前端或者接口的问题。直接查一下接口返回,能很快定位。
6.2 排查速查表
| 现象 | 最可能原因 | 快速验证方式 | 处理办法 |
|---|---|---|---|
| 页面一直空,日志无记录 | 域名解析未生效 | 本地查 MX 记录 | 等缓存过期,核对记录值 |
| 日志有连接但被拒收 | 未开启全收件人模式 | 看收信日志的拒收原因 | 关闭本地收件人校验 |
| 提示邮箱不可用,无发信记录 | 域名被平台拦截 | 换一个域再提交 | 启用备用域 |
| 收到重复邮件 | 收信端响应慢触发重试 | 看同内容邮件的时间间隔 | 收信端改成轻量落盘,异步解析 |
| 有信但页面不刷新 | 前端轮询逻辑异常 | 直接请求接口看返回 | 检查退避逻辑与错误处理 |
| 磁盘占用持续上涨 | 未执行空间回收 | 看数据库文件大小 | 定期执行 VACUUM |
| 收到大量垃圾投递 | 地址被公开扫到 | 看发信方是否集中 | 缩短 TTL,加单箱容量上限 |
| 到期后仍能查到旧信 | 只在定时任务里做过期判断 | 手动查一次过期数据 | 读取接口加上时间条件 |
6.3 几条不太好归类的心得
别在高峰期做注册流程测试。平台发信队列在高峰期限流明显,你测出来的延迟是不准的,容易误判成自己代码有问题。我一般选在流量低谷时段做这类验证。
验证码提取别做太死。见过有人写死“四位数字”,结果碰到六位字母加数字的模板直接失效。宽松一点,先匹配连续 4 到 8 位字母数字组合,抽不到就整段展示,让人自己看,比抽错了好。
自建的话,先只给自己用。开放给别人用之后,你要处理的是滥用、投诉、域名信誉下滑这一整套问题,投入会翻好几倍。个人的量级,一台小机器、一个域、一个页面,完全够。
保留一份“测试地址清单”。我习惯按项目维护一个表,记录每个项目用了哪个前缀、什么时间用的、什么时候可以清理。听起来有点笨,但比事后翻聊天记录找强得多。
我个人在实际操作中的体会是,临时邮箱这类工具的价值,八成在“隔离”这两个字上,剩下两成才是“免费”和“方便”。把它当成一个一次性的、随时可丢弃的信箱来用,你的主邮箱会清爽很多,被营销触达的概率也实打实地降下来。但如果你指望它承担匿名功能,那大概率会失望——它隔开的是一个地址,不是一整个身份。真正有效的隐私保护,从来都是好几层的组合,单靠一个工具解决不了,也不该指望它解决。