使用nodemailer发送ejs模板

18

我正在尝试使用express.js构建一个Web应用程序。 在我的应用程序中,我正在使用nodemailer发送邮件。 如果我只使用它来发送基本邮件,它可以正常工作; 但是,当我尝试使用nodemailer发送已呈现的ejs文件时,收件人只会收到一封空邮件。 因此,以下是我的代码详细信息:

var transporter = nodemailer.createTransport({
                host: 'smtp.zoho.com',
                port: 465,
                secure: true, // use SSL
                auth: {
                    user: 'testmail@zoho.com',
                    pass: '123456'
                }
            });
fs.readFile('/test.ejs', 'utf8', function (err, data) {
                if (err) {
                    return console.log(err);
                }
                var mainOptions = {
                    from: '"Tester" testmail@zoho.com',
                    to: email,
                    subject: 'Hello, world'
                    html: ejs.render(data, {name: 'Stranger'});
                };
                console.log(mainOptions.html);
});
transporter.sendMail(mainOptions, function (err, info) {
                            if (err) {
                                console.log(err);
                            } else {
                                console.log('Message sent: ' + info.response);
                            }
                        });

这里是test.ejs文件(同时,结果控制台打印的mainOptions.html也很好,因为它正确地输出了渲染后的ejs文件字符串(<%= name %>替换为“Stranger”))

<style type="text/css">
  .header {
    background: #8a8a8a;
  }
  .header .columns {
    padding-bottom: 0;
  }
  .header p {
    color: #fff;
    padding-top: 15px;
  }
  .header .wrapper-inner {
    padding: 20px;
  }
  .header .container {
    background: transparent;
  }
  table.button.facebook table td {
    background: #3B5998 !important;
    border-color: #3B5998;
  }
  table.button.twitter table td {
    background: #1daced !important;
    border-color: #1daced;
  }
  table.button.google table td {
    background: #DB4A39 !important;
    border-color: #DB4A39;
  }
  .wrapper.secondary {
    background: #f3f3f3;
  }
</style>



<wrapper class="header">
  <container>
    <row class="collapse">
      <columns small="6">
        <img src="http://placehold.it/200x50/663399">
      </columns>
      <columns small="6">
        <p class="text-right">BASIC</p>
      </columns>
    </row>
  </container>
</wrapper>

<container>

  <spacer size="16"></spacer>

  <row>
    <columns small="12">

      <h1>Hi, <%= name %></h1>
      <p class="lead">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Magni, iste, amet consequatur a veniam.</p>
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ut optio nulla et, fugiat. Maiores accusantium nostrum asperiores provident, quam modi ex inventore dolores id aspernatur architecto odio minima perferendis, explicabo. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima quos quasi itaque beatae natus fugit provident delectus, magnam laudantium odio corrupti sit quam. Optio aut ut repudiandae velit distinctio asperiores?</p>
      <callout class="primary">
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reprehenderit repellendus natus, sint ea optio dignissimos asperiores inventore a molestiae dolorum placeat repellat excepturi mollitia ducimus unde doloremque ad, alias eos!</p>
      </callout>
    </columns>
  </row>
  <wrapper class="secondary">

    <spacer size="16"></spacer>

    <row>
      <columns large="6">
        <h5>Connect With Us:</h5>
        <button class="facebook expand" href="http://zurb.com">Facebook</button>
        <button class="twitter expand" href="http://zurb.com">Twitter</button>
        <button class="google expand" href="http://zurb.com">Google+</button>
      </columns>
      <columns large="6">
        <h5>Contact Info:</h5>
        <p>Phone: 408-341-0600</p>
        <p>Email: <a href="mailto:foundation@zurb.com">foundation@zurb.com</a></p>
      </columns>
    </row>
  </wrapper>
</container>

如果我用简单的内容替换mainOptions.html,例如:<b>你好,世界!</b>,接收者将会准确地收到该内容。但是,如果我使用上述代码,接收者将只收到一个空内容的电子邮件(接收者仍然能够正确地接收发件人、主题和其他信息)。我已经尝试用文本替换html,并发送渲染后的字符串作为纯文本,但收到的邮件仍然是空内容。这是我目前可以提供的问题细节。所以,如果有人知道我的代码有什么问题,请指出来。

感谢您提供的任何帮助。

2个回答

38

问题在于sendMailfs.readFile完成之前就被执行了。

实际上,可以用ejs.renderFile替换readFile,它可以读取文件并呈现HTML字符串。请尝试下面的重构代码。

var fs = require("fs");
var nodemailer = require("nodemailer");
var ejs = require("ejs");
var transporter = nodemailer.createTransport({
    host: 'smtp.zoho.com',
    port: 465,
    secure: true, // use SSL
    auth: {
        user: 'testmail@zoho.com',
        pass: '123456'
    }
});

ejs.renderFile(__dirname + "/test.ejs", { name: 'Stranger' }, function (err, data) {
if (err) {
    console.log(err);
} else {
    var mainOptions = {
        from: '"Tester" testmail@zoho.com',
        to: "totest@zoho.com",
        subject: 'Hello, world',
        html: data
    };
    console.log("html data ======================>", mainOptions.html);
    transporter.sendMail(mainOptions, function (err, info) {
        if (err) {
            console.log(err);
        } else {
            console.log('Message sent: ' + info.response);
        }
    });
}

});

3
您先生是我今天的英雄 :-) - Richlewis

15

我已经使用ES6和ES8的特性更新了答案,以防有人需要。

不要忘记在异步函数中使用它。

const fs = require("fs");
const nodemailer = require("nodemailer");
const ejs = require("ejs");

const transporter = nodemailer.createTransport({
  host: 'smtp.zoho.com',
  port: 465,
  secure: true,
  auth: {
    user: 'testmail@zoho.com',
    pass: '123456'
  }
});

const data = await ejs.renderFile(__dirname + "/test.ejs", { name: 'Stranger' });

const mainOptions = {
  from: '"Tester" testmail@zoho.com',
  to: 'totest@zoho.com',
  subject: 'Hello, world!',
  html: data
};

transporter.sendMail(mainOptions, (err, info) => {
  if (err) {
    console.log(err);
  } else {
    console.log('Message sent: ' + info.response);
  }
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接