You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nodemailer发送邮件附件存在文件名但内容为空如何解决

问题根因

附件为空是3处代码错误共同导致的:

  • 前端未正确配置文件上传规则,实际只把浏览器生成的假文件路径传到了后端,根本没传输文件二进制内容
  • 后端未配置multipart格式解析逻辑,无法从请求中拿到真实文件数据
  • Nodemailer附件配置缺失必填的文件内容字段,同时存在MIME类型书写错误

第一步:修复前端上传配置

当前表单默认使用application/x-www-form-urlencoded编码,文件控件也未配置匹配后端的name属性,提交时只会传递文件名的假路径(就是MIME片段里看到的C:\fakepath\前缀内容),不会携带真实文件。
修改规则:

  • 给Form标签添加encType="multipart/form-data"属性,开启文件编码传输
  • 给文件选择控件添加name="fFileMultiple"属性,和后端接收字段名对应;如果需要支持多文件选择,额外添加multiple属性
  • 如果使用fetch/axios发送请求,必须用FormData对象封装请求体,不能用JSON格式传参

修改后的前端代码片段:

<Form 
  encType="multipart/form-data"
  {/* 保留原有method、onSubmit等属性 */}
>
  {/* 保留其他原有表单项 */}
  <Form.Group>
    <Form.Label>Multiple Photos Allowed</Form.Label>
    <Form.Control 
      type='file' 
      name='fFileMultiple'
      multiple
      accept='.jpg, .png, .jpeg' 
    />
  </Form.Group>
  <Button type='submit' value={"submit"}>
    {status}
  </Button>
</Form>

第二步:后端添加文件解析中间件

普通的请求体解析中间件(比如express.json()、express.urlencoded())无法解析multipart格式的文件内容,需要添加专门的文件处理中间件,以最常用的multer为例:

  1. 安装依赖:npm install multer
  2. 在服务入口文件引入并配置内存存储,直接把上传的文件暂存在内存中供邮件发送使用:
const multer = require('multer');
const upload = multer({ storage: multer.memoryStorage() });
  1. 给接收表单提交的路由添加中间件:单文件上传用upload.single('fFileMultiple'),多文件上传用upload.array('fFileMultiple')。添加后真实文件数据会存到req.file(单文件)或req.files(多文件)对象中,不再出现在req.body里。

第三步:修正Nodemailer附件配置

原附件配置只传了文件名和错误的MIME类型,完全缺失文件内容字段,这是MIME片段里附件部分为空的直接原因。另外JPEG格式的正确MIME类型是image/jpeg,不是你写的images/jpeg。
单文件场景下修改后的邮件发送代码如下:

// 路由示例:app.post('/submit-complaint', upload.single('fFileMultiple'), (req, res) => {
  const cName = req.body.cName;
  const cAddress = req.body.cAddress;
  const phone = req.body.phone;
  const email = req.body.email;
  const vName = req.body.vName;
  const vAddress = req.body.vAddress;
  const violation = req.body.violation;
  const uploadFile = req.file; // 从req.file取真实文件数据,不要从req.body取

  let mail = {
    from: "hello@gmail.com",
    to: "email@gmail.com",
    subject: `Complaint from ${cName} on ${vName}`,
    html: `The message is from ${cName} <br />
    Complaint's Name: ${cName} <br />
    Complaint's address: ${cAddress} <br />
    Email: ${email} <br />
    Phone: ${phone} <br />
    Violator's Name: ${vName} <br />
    Violator's Address: ${vAddress} <br />
    Violation: ${violation} <br />`,
    attachments: [
      {
        filename: uploadFile.originalname, // 自动取真实文件名,去掉fakepath假路径前缀
        contentType: uploadFile.mimetype, // 用上传时自动识别的MIME类型,无需硬写
        content: uploadFile.buffer // 传入文件二进制内容,为之前缺失的核心字段
      },
    ],
  };
  contactEmail.sendMail(mail, (error) => {
    if (error) {
      console.log(error);
      return res.status(500).send('发送失败');
    } else {
      console.log("Message has been sent");
      return res.send('发送成功');
    }
  });
// })

如果是多文件上传场景,遍历req.files数组生成attachments列表即可。


验证标准

修改完成后重新发送请求,导出邮件原始MIME信息,若附件的两个分隔符之间存在大段base64编码内容,说明文件已经正确携带,不会再出现空附件问题。

内容的提问来源于stack exchange,提问作者Terry Hunt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 17:39:22