如何在Next.js 14服务端用Nodemailer以Buffer/Stream发送PDF附件
解决Next.js 14服务端用Nodemailer通过Buffer发送PDF附件失败的问题
第一步:添加错误捕获,定位具体问题
你当前的代码缺少错误处理逻辑,无法得知发送失败的具体原因(比如编码错误、MIME类型缺失、邮件服务器配置问题等)。先给submittingEmail函数加上try/catch块,打印错误信息:
"use server"; import { mailOptions, transporter } from "../config/nodemailer"; interface EmailInputs { name: string; file: File | null; } export async function submittingEmail({ name, file }: EmailInputs) { if (!file) return; try { const arrayBuffer = await file.arrayBuffer(); const fileBuffer = Buffer.from(arrayBuffer); await transporter.sendMail({ ...mailOptions, attachments: [ { filename: file.name, // 保留用户上传的原文件名,避免硬编码 content: fileBuffer, contentType: "application/pdf", // 显式指定PDF的MIME类型 }, ], subject: `Testing Attachments`, text: "this a text", html: ` <!DOCTYPE html> <html> <body style="direction:rtl"> <h1 style="color:darkgreen; text-align: center;margin:0;font-size:24px">Testing Attachments</h1> <p>contact visitor name is : ${name}</p> </body> </html> `, }); console.log("邮件发送成功"); } catch (error) { console.error("邮件发送失败详情:", error); throw error; // 抛出错误方便前端处理或调试 } }
关键修正点
- 显式设置
contentType:Nodemailer默认可能无法自动识别Buffer对应的文件类型,指定application/pdf能确保邮件客户端正确解析PDF附件,避免因类型识别错误导致附件无法打开或发送失败。 - 使用原文件名:替换硬编码的
"test.pdf"为file.name,既符合用户预期,也能避免文件名格式不兼容的问题。 - 添加错误捕获:通过
try/catch获取具体错误信息,这是排查问题的核心——比如SMTP认证失败、Buffer数据损坏等问题,都能在控制台看到明确提示。
额外排查方向
如果添加上述代码后仍失败,根据打印的错误信息进一步定位:
- 若提示
Invalid attachment content:检查Buffer完整性,通过console.log(fileBuffer.length)对比原文件大小,确认转换过程中没有数据丢失。 - 若提示邮件服务器连接/认证错误:检查
transporter的SMTP配置(地址、端口、账号密码是否正确)。 - 若怀疑Next.js Server Action的File对象处理问题:可以尝试通过Base64中转转换Buffer,代码示例:
const base64Str = await new Promise<string>((resolve) => { const reader = new FileReader(); reader.onloadend = () => resolve((reader.result as string).split(",")[1]); reader.readAsDataURL(file); }); const fileBuffer = Buffer.from(base64Str, "base64");
内容的提问来源于stack exchange,提问作者Ayman Morsy
相关产品推荐
相关产品推荐

