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

如何通过Minio预签名URL获取PDF并直接用Nodemailer发送(不落地)

解决方案:直接通过流将Minio预签名URL的PDF作为Nodemailer附件发送

你不需要把文件保存到本地,Nodemailer支持直接用流对象作为附件内容,只要把HTTP请求拿到的响应流直接传给附件配置就行,完全跳过本地文件写入的步骤。

核心思路

用https.get请求预签名URL获取文件流,把这个响应流直接赋值给Nodemailer附件的content字段,Nodemailer会自动读取流内容并作为附件发送。

基础实现代码

const https = require('https');
const nodemailer = require('nodemailer');

// 初始化Nodemailer传输器(根据你的邮箱服务商配置)
const transporter = nodemailer.createTransport({
  service: 'Gmail', // 也可以替换成其他SMTP服务,比如QQ邮箱
  auth: {
    user: '你的邮箱地址',
    pass: '邮箱授权码或登录密码'
  }
});

// 请求Minio预签名URL获取PDF流
https.get(signedUrl, (res) => {
  // 检查请求是否成功
  if (res.statusCode !== 200) {
    console.error(`获取PDF失败,状态码:${res.statusCode}`);
    res.resume(); // 释放未使用的响应流资源
    return;
  }

  // 配置邮件参数
  const mailOptions = {
    from: '发件人邮箱 <sender@example.com>',
    to: '收件人邮箱 <recipient@example.com>',
    subject: '包含PDF附件的邮件',
    text: '请查看附件中的PDF文件',
    attachments: [
      {
        filename: 'sample.pdf', // 收件人看到的附件名称
        content: res, // 直接传入HTTP响应流
        contentType: 'application/pdf' // 指定文件MIME类型,确保客户端正确识别
      }
    ]
  };

  // 发送邮件
  transporter.sendMail(mailOptions, (error, info) => {
    if (error) {
      return console.error('邮件发送失败:', error);
    }
    console.log('邮件发送成功:', info.response);
  });
}).on('error', (err) => {
  console.error('请求预签名URL出错:', err);
});

进阶:用Async/Await优化异步流程

如果习惯用异步语法,可把流获取和邮件发送封装成Promise,让代码逻辑更清晰:

const https = require('https');
const nodemailer = require('nodemailer');

async function sendPdfByEmail(signedUrl) {
  try {
    // 初始化传输器
    const transporter = nodemailer.createTransport({
      service: 'Gmail',
      auth: {
        user: '你的邮箱',
        pass: '授权码'
      }
    });

    // 获取PDF流的Promise封装
    const getPdfStream = () => new Promise((resolve, reject) => {
      https.get(signedUrl, (res) => {
        if (res.statusCode !== 200) {
          reject(new Error(`获取PDF失败:状态码${res.statusCode}`));
          res.resume();
          return;
        }
        resolve(res);
      }).on('error', reject);
    });

    const pdfStream = await getPdfStream();

    // 发送邮件
    await transporter.sendMail({
      from: '发件人 <sender@example.com>',
      to: '收件人 <recipient@example.com>',
      subject: 'PDF附件邮件',
      text: '附件为Minio存储的PDF文件',
      attachments: [
        {
          filename: 'sample.pdf',
          content: pdfStream,
          contentType: 'application/pdf'
        }
      ]
    });

    console.log('邮件发送成功');
  } catch (err) {
    console.error('处理失败:', err);
  }
}

// 调用函数
sendPdfByEmail(signedUrl);

关键注意点

  • 彻底舍弃fs.createWriteStream,直接复用HTTP响应流即可
  • 必须指定contentType为application/pdf,避免邮件客户端无法识别附件类型
  • 要处理HTTP请求和邮件发送过程中的错误,防止资源泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 09:05:20