《林一的 Cloudflare 通关记》第 13 篇-连邮件也能搞定——Email Routing 邮件转发
《林一的 Cloudflare 通关记》第 13 篇
Access 配好后的第二天,小王风风火火地冲过来。
"林一,客户要个联系方式!我在官网上挂了个 contact@星火ai.com,但这个邮箱不存在啊,邮件发出去全弹回来了。"
故事引入
"那得搞个企业邮箱吧?"林一打开浏览器搜了搜,"阿里云企业邮箱,最低套餐 600 块一年。腾讯企业邮箱现在也要收费了……"
"又花钱?"老张不知道什么时候走到了背后,"你的域名在 Cloudflare 上吧?"
"对。"
"Cloudflare 有 Email Routing,免费帮你收邮件,转发到你个人邮箱就行。contact@星火ai.com 收到的邮件,自动转到你的 Gmail。"
"这么省?"
"创业公司不寒碜,能省则省。"老张坐下来,"不过它主要是收邮件的,发送邮件得另外想办法——Cloudflare 现在也有邮件发送功能,但需要 Workers 付费版。免费的方案也有,待会一起说。"
技术讲解
邮件收发的基本原理
"先快速过一下邮件是怎么收发的,"老张在白板上画了个简图:
发邮件(发送方 → 收件方):
发件人 → SMTP服务器 → 收件方SMTP服务器 → 收件人邮箱
收邮件(收件方 → 本地邮箱):
收件方SMTP服务器 ← MX记录指向 → 你的域名DNS
"关键在 MX 记录——它告诉互联网'发到 @星火ai.com 的邮件应该交给哪个服务器'。你把 MX 记录指向 Cloudflare,Cloudflare 就替你收邮件。"
"这个我知道,"林一点头,"就像 DNS 的 A 记录指向网站服务器一样,MX 记录指向邮件服务器。"
"对,不多说了。重点看 Cloudflare Email Routing 能干什么。"

Cloudflare Email Routing 的工作原理
老张画了张流程图:
客户发邮件到 contact@星火ai.com
│
▼
┌──────────────┐
│ Cloudflare │ ← MX记录指向Cloudflare
│ 邮件服务器 │
└──────┬───────┘
│ 根据转发规则匹配收件地址
▼
┌──────────────┐
│ 转发规则匹配 │ contact@ → 转发到 linyi@gmail.com
└──────┬───────┘
│ 转发邮件
▼
┌──────────────┐
│ 你的个人邮箱 │ linyi@gmail.com 收到邮件
└──────────────┘
"注意一个关键点:Cloudflare 不存储邮件。它只是个'转发站'——收到邮件,立刻按规则转发到你指定的目标邮箱。邮件最终存在你的 Gmail/QQ 邮箱里。"
"那和 Gmail 的自动转发有什么区别?"
"区别大了。Gmail 转发是'先收再转'——邮件先到 Gmail 服务器,再转发。而 Email Routing 是'域名级别'的——contact@星火ai.com 这个地址根本不存在实体邮箱,它就是个别名,Cloudflare 直接把邮件改投到你的真实邮箱。"
"相当于一个邮件层的反向代理?"
"没错!跟 Cloudflare 代理 HTTP 请求一个道理——用户访问的是 admin.星火ai.com,但实际响应的是你的 Worker。邮件也是——发件人发到 contact@星火ai.com,实际收到的是你的 Gmail。"

Email Routing 能做什么?
| 功能 | 说明 |
|---|---|
| 按地址转发 | contact@ → 你的邮箱,support@ → 客服邮箱 |
| Catch-all 转发 | 任何 @星火ai.com 的邮件都转发到一个邮箱 |
| Email Worker | 不转发,而是交给 Worker 处理——存数据库、调 API、自动回复 |
| 自动 DNS 配置 | 启用时自动添加 MX、SPF、DKIM 记录 |
国内类比:类似阿里云/腾讯云企业邮箱的"邮件转发"功能,但那些通常绑定在企业邮箱套餐里(需要付费),Cloudflare 的 Email Routing 是完全免费的,而且支持 Worker 编程化处理。

实操指导
第一步:启用 Email Routing
"开始配置。"老张打开 Cloudflare Dashboard。
- 进入 Cloudflare Dashboard → 选择你的域名
星火ai.com - 左侧菜单 → Email → Email Routing
- 第一次进入会看到引导页面,点击 Get started
Cloudflare 会自动帮你添加三条 DNS 记录:
| 记录类型 | 名称 | 值 | 作用 |
|---|---|---|---|
| MX | 星火ai.com | route1.mx.cloudflare.net(优先级 69) | 告诉互联网发到这个域名的邮件交给 Cloudflare |
| MX | 星火ai.com | route2.mx.cloudflare.net(优先级 4) | 备用 MX 服务器 |
| MX | 星火ai.com | route3.mx.cloudflare.net(优先级 13) | 备用 MX 服务器 |
| TXT | 星火ai.com | v=spf1 include:_spf.mx.cloudflare.net ~all | SPF 记录,授权 Cloudflare 处理你的邮件 |
| TXT | _dmarc | DMARC 策略 | DMARC 记录,防止邮件被冒充 |
"这些全都是自动的?"林一问。
"全自动。因为你域名 DNS 在 Cloudflare 上(还记得第 1 篇说的吗?域名托管在 Cloudflare 的好处),一键搞定。如果 DNS 不在 Cloudflare 上,你就得手动去注册商后台一条条加这些记录,光 MX 记录就三条,还有 SPF 和 DMARC……"
"又是一个'把域名放在 Cloudflare 上就省事'的理由。"
"对。DNS 托管、SSL 证书、CDN、邮件路由——全部一键打通。这就是生态的力量。"
- 点击 Done,等待 DNS 生效(通常 5-15 分钟)
第二步:添加目标邮箱
"转发到哪里?得先验证你的目标邮箱。"
- 在 Email Routing 页面 → Destination addresses 标签
- 输入你的个人邮箱,比如
linyi@gmail.com - Cloudflare 会发一封验证邮件到这个地址
- 打开邮件,点击 Verify email address
"为什么要验证?"
"防止你把邮件转发到一个不属于你的邮箱——不然任何人都能配置 ceo@apple.com 的转发规则了。"
"那能转发到多个邮箱吗?"
"可以。每个目标地址都要单独验证。验证一次以后,所有域名下的转发规则都能复用。"
第三步:创建转发规则
"现在来配 contact@ 邮箱。"
- 在 Email Routing 页面 → Routing rules 标签
- 点击 Create routing rule
配置规则:
| 字段 | 填写 | 说明 |
|---|---|---|
| Email pattern | contact | 匹配 contact@星火ai.com |
| Action | Send to an email | 转发到邮箱 |
| Destination | linyi@gmail.com | 你刚验证的目标邮箱 |
- 点击 Save
"来试试。"老张用自己的手机给 contact@星火ai.com 发了封测试邮件。
30 秒后,林一的 Gmail 收到了。
"成了!"林一兴奋地打开邮件,发件人显示的是老张的邮箱地址,但收件人是 contact@星火ai.com。
"注意看,"老张指了指邮件头,"Cloudflare 会加一个 X-Forwarded-To 的头,标识这封邮件是转发过来的。"
第四步:配置 Catch-all(全量接收)
"如果有人发到 random@星火ai.com,但你没有配转发规则怎么办?"
"弹回去?"
"默认是的。但你可以开 Catch-all——所有没匹配到规则的邮件,统一转发到一个邮箱。"
- 在 Routing rules 页面底部找到 Catch-all address
- 开启开关
- Action 选 Send to an email,目标选你的邮箱
- 保存
"这样不管别人发到 support@、hr@ 还是 abcdef@,全都能收到。"

"这个功能好!"小王凑过来看,"我以后名片上印 xiaowang@星火ai.com,邮件直接到我邮箱,还不用单独配。"
"对,Catch-all 就是个'万能收件箱'。不过要注意垃圾邮件——开了 Catch-all 意味着所有地址都能收到邮件,垃圾邮件也会进来。建议配合 Cloudflare 的邮件过滤使用。"
第五步:Email Worker——用代码处理邮件
"光转发还不够酷,"老张搓了搓手,"Email Routing 还能跟 Workers 结合——收到邮件后不转发,而是交给 Worker 处理。"
"能干什么?"
"什么都行——存到 D1 数据库、调 AI 分析邮件内容、自动回复、转发到 Slack Webhook……你写代码就行。"
"来个实际例子——收到客户邮件自动存到数据库并发送确认回信。"
先在 wrangler.toml 里配置 Email Worker:
name = "email-handler"
main = "src/index.js"
compatibility_date = "2024-09-01"
# Email Routing 绑定
[[email]]
name = "EMAIL_HANDLER"
# D1 数据库绑定(第9篇配的)
[[d1_databases]]
binding = "DB"
database_name = "xinghuo-db"
database_id = "你的数据库ID"
Worker 代码:
export default {
// 处理 HTTP 请求(正常的 API)
async fetch(request, env, ctx) {
return new Response("Email Worker is running");
},
// 处理收到的邮件
async email(message, env, ctx) {
// 1. 获取邮件信息
const from = message.from; // 发件人
const to = message.to; // 收件人
const subject = message.headers.get("subject"); // 邮件主题
// 2. 读取邮件正文
const rawEmail = await new Response(message.raw).text();
// 3. 存到 D1 数据库
await env.DB.prepare(
`INSERT INTO emails (from_address, to_address, subject, body, created_at)
VALUES (?, ?, ?, ?, datetime('now'))`
).bind(from, to, subject, rawEmail).run();
// 4. 同时转发到林一的个人邮箱(保留转发功能)
await message.forward("linyi@gmail.com");
// 5. 记录日志
console.log(`收到邮件: ${from} → ${to} | 主题: ${subject}`);
},
};
"看到了吧?email() 这个 handler 就是专门处理收到的邮件的。message 对象里有发件人、收件人、邮件头和原始邮件内容。你可以读邮件内容、存数据库、转发、调 API——什么都行。"
"那怎么把 Worker 和 Email Routing 绑定?"
"在 Email Routing 的 Routing rules 里,Action 不选 'Send to an email',而是选 Send to a Worker,然后选你部署好的 Email Worker。"
Routing rule:
Email pattern: contact@星火ai.com
Action: Send to a Worker
Worker: email-handler
"这样 contact@星火ai.com 收到的邮件就不会转发到邮箱了,而是交给 Worker 处理。Worker 里你可以同时做转发和存库——两不误。"

发送邮件怎么办?
"收邮件搞定了,"林一问,"那发邮件呢?小王说要从 contact@星火ai.com 给客户回邮件。"
"这个确实是 Email Routing 的短板——它只管收,不管发。"老张想了想,"不过现在有几个方案。"

方案一:Cloudflare Email Sending(官方方案,需付费)
"Cloudflare 2024 年底推出了邮件发送功能,目前是 Beta。可以直接在 Worker 里用 EMAIL binding 发邮件:
// wrangler.toml
// [[send_email]]
// name = "EMAIL"
export default {
async fetch(request, env, ctx) {
await env.EMAIL.send({
to: "customer@example.com",
from: "contact@星火ai.com",
subject: "感谢您的来信",
html: "<h1>您好!</h1><p>我们已收到您的邮件,会尽快回复。</p>",
text: "您好!我们已收到您的邮件,会尽快回复。",
});
return new Response("邮件已发送");
},
};
"代码很简洁,但问题是——这个功能目前需要 Workers Paid Plan(每月 $5)。免费版用不了。"
方案二:用 Gmail 代发(免费)
"最省钱的方案——在 Gmail 设置里添加'以其他地址发送邮件',通过 Gmail 的 SMTP 服务器以 contact@星火ai.com 的身份发邮件。"
- Gmail → 设置 → 账户和导入 → "添加其他电子邮件地址"
- 输入
contact@星火ai.com - SMTP 服务器填 Gmail 的(
smtp.gmail.com,端口 587) - 用你自己的 Gmail 账号验证
"这样你在 Gmail 里写信,发件人可以选 contact@星火ai.com。收件人看到的就是企业邮箱地址,但实际通过 Gmail 发出。"
"免费?"
"完全免费。但注意——这种方式发出去的邮件,SPF 和 DKIM 验证可能不完美,有些严格的邮箱(比如 Outlook)可能标记为可疑。对于创业公司初期够用了。"
方案三:第三方邮件服务(免费额度)
"如果需要从代码里发邮件(比如注册确认邮件、密码重置),用第三方邮件 API:
| 服务 | 免费额度 | 特点 |
|---|---|---|
| Resend | 每月 3000 封 / 100 封/天 | API 友好,有 Node SDK |
| Brevo (Sendinblue) | 每月 300 封 | 老牌服务 |
| Mailgun | 前 3 个月 5000 封/月 | 之后付费 |
"在 Worker 里调这些服务的 API 就行,几十行代码搞定。"
// 用 Resend 发邮件的示例
export default {
async fetch(request, env, ctx) {
const res = await fetch("https://api.resend.com/emails", {
method: "POST",
headers: {
"Authorization": `Bearer ${env.RESEND_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
from: "contact@星火ai.com",
to: "customer@example.com",
subject: "感谢您的来信",
html: "<p>我们已收到您的邮件</p>",
}),
});
return new Response("邮件已发送");
},
};
"把 RESEND_API_KEY 放到 Worker 的环境变量里就行。"
Email Routing 的局限性
"总结一下 Email Routing 的限制,别踩坑:"
| 限制 | 说明 |
|---|---|
| 只能收不能发 | Email Routing 本身只处理入站邮件,发邮件需要其他方案 |
| 不存储邮件 | 邮件收到后立即转发/处理,不会存在 Cloudflare 上 |
| 需要 Cloudflare DNS | MX 记录必须在 Cloudflare 上管理,不能用其他 DNS |
| 转发延迟 | 通常几秒到几分钟,不是实时的 |
| 附件大小限制 | 25MB(与标准邮件一致) |
| 目标邮箱需验证 | 转发目标必须先验证所有权 |
小结与预告
本篇知识点回顾
| 知识点 | 要点 |
|---|---|
| Email Routing 原理 | MX 记录指向 Cloudflare → 收到邮件 → 按规则转发/处理 |
| 自动 DNS 配置 | 启用时自动添加 MX、SPF、DKIM 记录(域名需在 Cloudflare 上) |
| 转发规则 | 按地址匹配转发到指定邮箱 |
| Catch-all | 所有未匹配的邮件统一转发,适合小团队 |
| Email Worker | email() handler 处理收到的邮件,可存库/调 API/自动回复 |
| 发送邮件方案 | Cloudflare Email Sending(付费)/ Gmail 代发(免费)/ Resend 等(免费额度) |
| 局限性 | 只收不发、不存储、需 Cloudflare DNS |
动手挑战
基础挑战:在你的域名上启用 Email Routing,配置 contact@你的域名 转发到你的个人邮箱。用另一个邮箱发测试邮件,确认能收到。
进阶挑战:写一个 Email Worker,收到邮件后把发件人、主题、时间存到 D1 数据库(参考第 9 篇的 D1 操作),同时自动回复一封"我们已收到您的邮件"的确认信。提示:
wrangler.toml里配置[[email]]和[[d1_databases]]绑定email()handler 里读邮件内容、写数据库- 用 Resend API 或 Cloudflare Email Sending 发送确认回信
思考题:如果你开了一个
support@邮箱,想收到邮件后自动在 Slack 群里发一条通知——你会怎么实现?(提示:Email Worker + Slack Webhook URL,fetch()发 POST 请求到 Slack 的 Incoming Webhook 地址。)
下回预告
"邮件搞定了!"小王满意地走了。林一长舒一口气,转头看老张。
"张哥,功能差不多齐了吧?DNS、SSL、CDN、Pages、Workers、AI、R2、KV、D1、Turnstile、WAF、Access、Email——还差啥?"
"上线前还有一件事。"老张指着 Dashboard 上的一个标签页。
"Analytics?"
"你的网站跑得快不快?哪里慢?有多少人访问?有没有出错?这些你都不知道就上线,那叫'蒙眼狂奔'。明天教你看看数据——上线前的体检报告。"
下篇预告:《上线前的"体检报告"——Analytics 与性能监控》
