Nodemailer:如何在文件中正确发送"stored"的html消息?



我想通过使用存储为html文件的消息而不是"硬编码"的消息来简化使用Nodemailer发送html消息的过程。消息字符串。然而,由于某些原因,Nodemailer并没有像我期望的那样工作。

下面的代码工作得很好(带有"硬编码"的版本)消息字符串):

const nodemailer = require('nodemailer');
const fs = require('fs');
let htmlMessage = "";
// Retrieve message from file
fs.readFile("./Message.html", 'utf8', (err, data) => {
if (err) throw err;
console.log(data)
htmlMessage = data;
});
console.log(htmlMessage);
// 1.) Define "transporter"
const transporter = nodemailer.createTransport({
service: ...,
auth: {
user: ...,
pass: ...
}
})
// 2.) Configure email
const email = {
from: ...,
text: 'This is a test! (Plain Text)',

// html: htmlMessage
html: '<div style="margin: 1em; padding: 0.5em; background-color: rgb(90, 168, 90); font-size: 1.5em; '
+ 'border-radius: 0.5em; font-family: Arial, Helvetica, sans-serif;"> '
+ 'This is a test!'
+ '</div>'
};
// 3.) Send email
transporter.sendMail(email, (error, info) => { if (error) {
console.error(error); } else {
console.log('Message sent: %s', info.messageId); }
});

但是,如果我像这样更改消息…

// 2.) Configure email
const email = {
from: ...,
text: 'This is a test! (Plain Text)',
html: htmlMessage
/*
html: '<div style="margin: 1em; padding: 0.5em; background-color: rgb(90, 168, 90); font-size: 1.5em; '
+ 'border-radius: 0.5em; font-family: Arial, Helvetica, sans-serif;"> '
+ 'This is a test!'
+ '</div>'
*/
};

…并替换"硬编码">

Message.html

<div style="margin: 1em;
padding: 0.5em;
background-color: rgb(90, 168, 90);
font-size: 1.5em;
border-radius: 0.5em;
font-family: Arial, Helvetica, sans-serif;">
This is a test!
</div>

…发送HTML内容不再工作。我只收到了"纯文本版本"。由于某些原因,Nodemailer失败了。我做错了什么?

你的问题是初学者对异步代码的常见误解之一。

在你的代码中你这样做了:

let htmlMessage = "";
// 1.) Retrieve message from file
fs.readFile("./Message.html", 'utf8', (err, data) => {
// 3.) Callback completes
if (err) throw err;
console.log(data)
htmlMessage = data;
});
// ....
console.log(htmlMessage); // SHOULD show empty string
// 2.) Configure email
const email = {
from: ...,
text: 'This is a test! (Plain Text)',
html: htmlMessage
};

可以看到,代码执行1.),然后执行2.),然后在之后执行几毫秒你的邮件是3.)。在阅读HTML文件之前,你基本上已经发送了电子邮件。

你需要做的是:

let htmlMessage = "";
// 1.) Retrieve message from file
fs.readFile("./Message.html", 'utf8', (err, data) => {
// 2.) Callback completes
if (err) throw err;
console.log(data)
htmlMessage = data;
// ...
// 3.) Configure email
const email = {
from: ...,
text: 'This is a test! (Plain Text)',
html: htmlMessage
};
});

或者,如果您更喜欢阅读原始代码的流程,您可以承诺使用fs.readFile()并使用async/await:

const util = require('util');
const readFile = util.promisify(fs.readFile);
async function foo () {
// 1.) Retrieve message from file
let htmlMessage = await readFile("./Message.html", 'utf8');
// ....
// 2.) Configure email
const email = {
from: ...,
text: 'This is a test! (Plain Text)',
html: htmlMessage
};
}
foo();

最新更新