Next.js中使用Nodemailer发邮件插图片报ENOENT错误如何解决?
Next.js API路由使用Nodemailer内嵌图片解决方案
错误原因
报错
ENOENT: no such file or directory, open '/images/welcome.png'是因为/images/welcome.png是Next.js提供给前端访问的静态资源路由,并非Node.js服务端运行时可直接读取的文件系统物理路径。API路由运行在Node.js环境下,需要传入静态资源在服务端的实际绝对路径才能读取文件。
实现步骤
- 确认资源存放位置
将需要内嵌的welcome.png放在项目根目录下的public/images/目录中,Next.js默认会将public目录下的所有文件作为静态资源托管。 - 拼接服务端可识别的文件路径
使用Node.js内置的path模块配合process.cwd()(Next.js运行时的工作目录默认为项目根目录)拼接真实路径:
import path from 'path'; const imageRealPath = path.join(process.cwd(), 'public', 'images', 'welcome.png');
- 配置Nodemailer内嵌图片
通过attachments配置项添加图片附件,并指定唯一的cid(内容ID),在邮件HTML内容中通过cid:${cid值}的格式引用图片。
完整代码示例
以下为App Router模式下app/api/send-email/route.js的示例代码,Pages Router可对应调整handler写法:
import nodemailer from 'nodemailer'; import path from 'path'; import fs from 'fs'; export async function POST(request) { // 拼接图片真实物理路径 const welcomeImgPath = path.join(process.cwd(), 'public', 'images', 'welcome.png'); // 前置校验文件是否存在,方便排查问题 if (!fs.existsSync(welcomeImgPath)) { return Response.json({ msg: '图片资源不存在' }, { status: 404 }); } // 初始化邮件传输器,根据你的邮箱服务商修改配置 const transporter = nodemailer.createTransport({ host: 'smtp.你的邮箱服务商.com', port: 465, secure: true, auth: { user: '你的邮箱地址', pass: '你的邮箱授权码' } }); // 邮件配置 const mailConfig = { from: '通知 <xxx@yourdomain.com>', to: '收件人邮箱地址', subject: '欢迎注册', // 邮件HTML内容中使用cid引用附件 html: ` <div style="text-align: center;"> <h2>欢迎加入我们的平台</h2> <img src="cid:welcome_banner" alt="欢迎横幅" style="width: 100%; max-width: 600px;" /> <p>感谢你的注册,祝你使用愉快</p> </div> `, attachments: [ { filename: 'welcome.png', path: welcomeImgPath, cid: 'welcome_banner' // 此处cid值需和HTML中cid:后面的内容完全一致 } ] }; try { await transporter.sendMail(mailConfig); return Response.json({ success: true, msg: '邮件发送成功' }); } catch (err) { console.error('邮件发送失败', err); return Response.json({ success: false, msg: '邮件发送失败' }, { status: 500 }); } }
注意事项
- 如果你不想将图片放在
public目录,也可以存放在项目其他目录(如src/assets/images/),只需修改路径拼接的参数即可:path.join(process.cwd(), 'src', 'assets', 'images', 'welcome.png') - 部署到Vercel等平台时,默认配置下
public目录和项目内的静态资源文件都会被打包到运行环境中,无需额外配置 - 多个内嵌图片只需在
attachments数组中添加多个附件配置,每个附件对应唯一的cid即可
内容的提问来源于stack exchange,提问作者ahmdtalat
相关产品推荐
相关产品推荐

