节点 imap 显示电子邮件

Node-imap displaying emails

我一直在尝试正确显示电子邮件,但未能成功。我刚刚给自己发送了电子邮件,当我在 hotmail 中打开它时它看起来像这样但是当我使用 node-imap 在我的应用程序中打开它时,从 'Sent box' 它看起来像这样(注意那些'=' 符号,以及其他一些奇怪的东西..):

这与控制台中的消息输出相同(出于某种原因,我在每一行的末尾得到“=”,在每个“=”之后得到“3D”):

现在...相同的消息,相同的方法,刚刚从收件箱中打开: http://prntscr.com/jbqtyw

只是一个纯文本..也在控制台中:http://prntscr.com/jbquba

我知道它的问题很麻烦而且很难理解,但不能让它变得更简单。这是获取电子邮件的 get() 代码:

get(id, params) {
    this.emailUsername = params.user.businessEmail;
    this.emailPassword = params.user.businessEmailPassword;
    this.host = params.user.serverIMAP;
    this.port = params.user.portIMAP;
    this.tls = params.user.serverSMTP;
    this.smtpPort = params.user.portSMTP;

    let currBox = params.query.box;
    let userEmail = this.emailUsername;

    return new Promise((resolve, reject) => {
      var imap = new Imap({
        user: this.emailUsername,
        password: this.emailPassword,
        host: this.host,
        port: this.port,
        tls: this.tls,
        tlsOptions: {
          rejectUnauthorized: false
        }
      });
      var response = {};

      function toUpper(thing) { return thing && thing.toUpperCase ? thing.toUpperCase() : thing; }

      function findAttachmentParts(struct, attachments) {
        attachments = attachments || []
        struct.forEach((i) => {
          if (Array.isArray(i)) findAttachmentParts(i, attachments)
          else if (i.disposition && ['INLINE', 'ATTACHMENT'].indexOf(toUpper(i.disposition.type)) > -1) {
            attachments.push(i)
          }
        })
        return attachments
      }

      function checkEmail(email) {
        return email.split('@')[1].split('.')[0];
      }

      function findTextPart(struct) {
        for (var i = 0, len = struct.length, r; i < len; ++i) {
          if (Array.isArray(struct[i])) {
            if (r = findTextPart(struct[i]))
              return r;
          } else if (struct[i].type === 'text'
            && struct[i].subtype === 'html') {
              return [struct[i].partID, struct[i].type + '/' + struct[i].subtype];
            } else if(struct[i].type === 'text'&& struct[i].subtype === 'plain') {
              return [struct[i].partID, struct[i].type + '/' + struct[i].subtype];
            }
        }
      }

      function getMsgByUID(uid, cb, partID) {
        var f = imap.seq.fetch(uid,
          (partID
            ? {
              bodies: [
                'HEADER.FIELDS (TO FROM SUBJECT DATE CC BCC)',
                partID[0]
              ]
            }
            : { struct: true })),
          hadErr = false;

        if (partID)
          var msg = { header: undefined, body: '', attrs: undefined };

        f.on('error', function (err) {
          hadErr = true;
          cb(err);
        });

        if (!partID) {
          f.on('message', function (m) {
            m.on('attributes', function (attrs) {
              partID = findTextPart(attrs.struct);
              const attachments = findAttachmentParts(attrs.struct);
              attachments.forEach((attachment) => {
                const filename = attachment.params.name  // need decode disposition.params['filename*'] !!!
                const encoding = toUpper(attachment.encoding)
                const f = imap.fetch(attrs.uid, { bodies: [attachment.partID] })
              })
            });
          });
          f.on('end', function () {
            if (hadErr)
              return;
            if (partID)
              getMsgByUID(uid, cb, partID);
            else
              cb(new Error('No text part found'));
          });
        } else {
          f.on('message', function (m) {
            m.on('body', function (stream, info) {
              var b = '';
              stream.on('data', function (d) {
                b += d;
              });
              stream.on('end', function () {
                if (/^header/i.test(info.which))
                  msg.header = Imap.parseHeader(b);
                else
                  msg.body = b;
                  console.log(b);
              });
            });
            m.on('attributes', function (attrs) {
              msg.attrs = attrs;
              msg.contentType = partID[1];
            });
          });
          f.on('end', function () {
            if (hadErr)
              return;
            cb(undefined, msg);
          });
        }
      }

      imap.once('ready', function () {
        imap.openBox(currBox, true, function (err, box) {
          if (err) throw err;
          getMsgByUID(id, function (err, msg) {
            if (err) throw err;
            response = msg;
            imap.end();
          });
        });
      });


      imap.once('error', function (err) {
        reject(err);
      });

      imap.once('end', function () {
        resolve(response);
      });

      imap.connect();
    })

  }

在前端,只是将其显示为内部 HTML:

<div class="content" [innerHtml]="bypassSecurity(email.body)">
    </div>

所以总而言之.. 同样 method/call 从流中得到不同的输出(一次是纯文本,一次是 html 文本.. 在这两种情况下,消息中都添加了一些奇怪的东西,比如 ' =' 或 '3D' 似乎是随机位置)?这是阅读电子邮件的正确方式吗?

这是 Quoted Printable 编码。

看来您可能需要撤消这些部分的内容传输编码,通常可以是 Base64 或 Quoted Printable。