You need to enable JavaScript to run this app. Next.js中使用Nodemailer发邮件插图片报ENOENT错误如何解决?
优惠活动
大模型
产品
解决方案
定价
更多

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环境下,需要传入静态资源在服务端的实际绝对路径才能读取文件。

实现步骤

  1. 确认资源存放位置
    将需要内嵌的welcome.png放在项目根目录下的public/images/目录中,Next.js默认会将public目录下的所有文件作为静态资源托管。
  2. 拼接服务端可识别的文件路径
    使用Node.js内置的path模块配合process.cwd()(Next.js运行时的工作目录默认为项目根目录)拼接真实路径:
import path from 'path';
const imageRealPath = path.join(process.cwd(), 'public', 'images', 'welcome.png');
  1. 配置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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.15 20:57:02