如何在 Vercel 上正确发送邮件(解决本地正常但部署后静默失败的问题)

13次阅读

如何在 Vercel 上正确发送邮件(解决本地正常但部署后静默失败的问题)

vercel 默认 edge 运行时限制了 node.js 原生网络模块的使用,导致 resend/nodemailer 等邮件客户端在部署后无报错、无响应。需显式声明 `runtime: ‘nodejs‘` 并启用动态路由,才能确保邮件 api 正常调用。

在 Vercel 上发送邮件失败(如日志停在 console.log(‘subject’, subject) 后不再继续),并非因免费账户限制——Vercel 本身不提供 SMTP 服务,也不拦截邮件请求;真正原因是其默认运行时行为:

edge functions(默认):基于 WebAssembly 的轻量运行时,不支持 node:net、node:tls 等底层模块,而 Resend SDK(v3+)和绝大多数邮件库(包括 Nodemailer)底层依赖这些模块发起 httpS 请求。即使使用 fetch,Edge 环境对 Content-Type、重定向、证书验证等也有更严格限制,易导致静默挂起或连接超时。

Node.js serverless Functions(需显式启用):完整兼容 CommonJS/ESM、原生 Node 模块及标准 https/http 客户端,是调用 Resend、SendGrid、Nodemailer 等服务的唯一可靠选择

✅ 正确配置方式(以 Resend 为例)

在你的 API 路由文件(如 app/api/send/route.ts 或 pages/api/send.ts)顶部添加:

// app/api/send/route.ts export const runtime = 'nodejs'; // 关键:强制使用 node.js 运行时 export const dynamic = 'force-dynamic'; // 确保每次请求都执行,避免缓存干扰  import { Resend } from 'resend'; import { NextResponse } from 'next/server';  export async function POST(request: Request) {   try {     const { to, subject, html } = await request.json();      console.log('sendEmail - start');     console.log('to:', to);     console.log('subject:', subject);      const resend = new Resend(process.env.RESEND_API_KEY!);     const response = await resend.emails.send({       from: process.env.SMTP_FROM_EMAIL!,       to,       subject,       html,     });      console.log('Resend success:', response);     return NextResponse.json({ success: true, data: response });   } catch (error) {     console.error('Email send error:', error);     return NextResponse.json(       { success: false, error: (error as Error).message },       { status: 500 }     );   } }

⚠️ 注意事项:runtime = ‘edge’ ❌ 是错误方案(官方文档旧示例已过时);Edge 下 Resend v3+ 会因缺少 node:crypto/node:stream 等模块直接抛 ReferenceError,但 Vercel 日志可能截断错误,造成“无输出”假象。环境变量必须在 Vercel 项目设置中配置(Settings → Environment Variables),且不能仅在本地 .env 中定义;RESEND_API_KEY 和 SMTP_FROM_EMAIL 需标记为 Production 作用域。若使用 pages/api 路由,请确保导出 config 对象(Next.js 13–14 兼容写法):export const config = { runtime: ‘nodejs’ };

? 验证是否生效

部署后访问 Vercel 日志(Dashboard → Your Project → Logs),成功调用应显示完整日志链:

sendEmail - start   to: user@example.com   subject: Test Email   Resend success: { id: "xxx", ... }

若仍卡住,请检查:

  • 是否误将 runtime 写在 async function 内部(必须为顶层导出);
  • RESEND_API_KEY 是否拼写错误或未保存到 Vercel 后台;
  • HTML 内容是否含非法字符(如未转义

✅ 总结

Vercel 不限制邮件发送功能本身,也无需升级 Pro 计划——关键在于匹配运行时环境。只要将函数明确指定为 runtime: ‘nodejs’,即可稳定调用 Resend、SendGrid、Mailgun 或自建 SMTP(Nodemailer)。这是 Vercel 官方推荐且生产验证的实践方式。

text=ZqhQzanResources