Nodemailer отправляет URI данных base64 в качестве вложения. Как?

В основном у меня есть изображение, созданное с использованием Canvas, и оно находится в URI данных в кодировке base64. Этот URI данных затем прикрепляется к электронной почте.

...,
 attachments:[{
 filename: "cat.jpg",
 contents: new Buffer(cat, 'base64')
}],

Письмо получено, но вложение не просматривается. Запуск $ file cat.jpg в Linux возвращает:

cat.jpg: ASCII text, with very long lines, with no line terminators

Почему это ASCII? Я уже упоминал base64. Как я могу решить эту проблему? Спасибо.


person Ильич Ленин    schedule 11.06.2014    source источник


Ответы (4)


Переменная cat, вероятно, включает часть 'data:image/jpeg;base64'. Вы не должны передавать этот бит Buffer.from.

Кажется, что если вы передаете неверные данные, Buffer.from() не жалуется:

var pixel = "data:image/gif;base64,"
    + "R0lGODlhAQABAIABAP///wAAACH5"
    + "BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
var buffer = Buffer.from(pixel, "base64"); // does not throw an error.

Вы даже получите действительный буфер. Буфер представляет собой поврежденное изображение (точнее, оно не начинается с заголовка изображения).

Вы должны самостоятельно удалить первую часть URI данных:

var buffer = Buffer.from(pixel.split("base64,")[1], "base64");

Изменить (май 2021 г.): изменено new Buffer на Buffer.from, так как первое устарело.

person RickN    schedule 11.06.2014
comment
Теперь это работает. Мне просто любопытно, вы знали об этом или проверяли? - person Ильич Ленин; 12.06.2014
comment
Не уверен, правильно ли я интерпретирую ваш вопрос, но: я знаю, что Nodemailer хочет допустимый буфер изображения, и я проверил, что new Buffer(stringWithPrefix) создает поврежденное изображение, а new Buffer(stringWithoutPrefix) — нет. Я мог видеть, что конструктор не вызывает ошибки и что два буфера не начинаются с одинаковых байтов (как ожидалось). Записал файлы на диск и проверил их целостность. Это отвечает на ваш вопрос? - person RickN; 12.06.2014

Буфер не нужен. Вы можете просто поместить в него строку, начинающуюся за префиксом кодировки base64:

var cat = "...base64 encoded image...";
var mailOptions = {
  ...
  attachments: [
    {   // encoded string as an attachment
      filename: 'cat.jpg',
      content: cat.split("base64,")[1],
      encoding: 'base64'
    }
  ]
};

Более подробную информацию вы найдете здесь: https://github.com/nodemailer/nodemailer#attachments

person lohsie    schedule 03.02.2016

Вы можете просто использовать пакет nodemailer-base64-to-s3.

Установите пакет:

npm install -s nodemailer-base64-to-s3

Настройте его с помощью nodemailer:

var base64ToS3 = require('nodemailer-base64-to-s3');
var nodemailer = require('nodemailer');

var transport = nodemailer.createTransport({});
transport.use('compile', base64ToS3(opts));

https://github.com/ladjs/nodemailer-base64-to-s3

person niftylettuce    schedule 20.09.2017

Для этого можно просто использовать path без дополнительных манипуляций:

    let attachments = [
        {
            filename: "image.gif",
            path: "data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
        }
    ]

Здесь ссылка на соответствующую документацию.

person vir us    schedule 14.01.2020