我正在开发带有基本联系表单的 MERN 应用程序,该表单使用 Nodemailer 发送电子邮件。我想要来自服务器的某种响应可以显示在前端,例如“邮件已发送”或“邮件未发送”等...
这是我的第一次尝试(来自 server.js 的代码),基于示例 here :
myRoutes.route('/send-mail').post(async function(req, res) {
let testAccount = await nodemailer.createTestAccount();
// create reusable transporter object using the default SMTP transport
let transporter = nodemailer.createTransport({
host: 'smtp.ethereal.email',
port: 587,
secure: false, // true for 465, false for other ports
auth: {
user: testAccount.user, // generated ethereal user
pass: testAccount.pass // generated ethereal password
}
});
let senderName = req.body.senderName;
let senderEmail = req.body.senderEmail;
let subject = req.body.subject;
let message = req.body.message;
let toEmail = req.body.toEmail;
// send mail with defined transport object
let info = await transporter.sendMail({
from: `"${senderName}" <${senderEmail}>`, // sender address
to: toEmail, // receiver address
subject: subject, // Subject line
text: message, // plain text body
html: message
});
console.log('Message sent: %s', info.messageId);
// Message sent: <b658f8ca-6296-ccf4-8306-87d57a0b4321@example.com>
// Preview only available when sending through an Ethereal account
console.log('Preview URL: %s', nodemailer.getTestMessageUrl(info));
// Preview URL: https://ethereal.email/message/WaQKMgKddxQDoou...
});
这可行(邮件已发送,预览 URL 已记录到控制台),但对服务器的 post 请求只是挂起,直到最终超时。因此,由于无论如何我都需要这样做,为了从服务器获取响应并通知前端用户,我想我应该在 sendMail 函数之后添加一个回调。
带回调的代码:
myRoutes.route('/send-mail').post(async function(req, res) {
let testAccount = await nodemailer.createTestAccount();
// create reusable transporter object using the default SMTP transport
let transporter = nodemailer.createTransport({
host: 'smtp.ethereal.email',
port: 587,
secure: false, // true for 465, false for other ports
auth: {
user: testAccount.user, // generated ethereal user
pass: testAccount.pass // generated ethereal password
}
});
let senderName = req.body.senderName;
let senderEmail = req.body.senderEmail;
let subject = req.body.subject;
let message = req.body.message;
let toEmail = req.body.toEmail;
// send mail with defined transport object
let info = await transporter.sendMail({
from: `"${senderName}" <${senderEmail}>`, // sender address
to: toEmail, // receiver address
subject: subject, // Subject line
text: message, // plain text body
html: message
},function(){
res.json('Mail sent!');
}).catch(err => {
res.json("Couldn't send the mail for some reason");
});
console.log('Message sent: %s', info.messageId);
// Message sent: <b658f8ca-6296-ccf4-8306-87d57a0b4321@example.com>
// Preview only available when sending through an Ethereal account
console.log('Preview URL: %s', nodemailer.getTestMessageUrl(info));
// Preview URL: https://ethereal.email/message/WaQKMgKddxQDoou...
});
这会收到“邮件已发送!”来自服务器的响应,但服务器抛出此错误:UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'catch' of undefined
,并且它不记录 messageID 或预览 url,所以我不确定是否确实发送了邮件。
我尝试在 catch 之前将 err
作为参数传递给函数,但这没有帮助。
我还尝试完全删除捕获(见下文):
myRoutes.route('/send-mail').post(async function(req, res) {
let testAccount = await nodemailer.createTestAccount();
// create reusable transporter object using the default SMTP transport
let transporter = nodemailer.createTransport({
host: 'smtp.ethereal.email',
port: 587,
secure: false, // true for 465, false for other ports
auth: {
user: testAccount.user, // generated ethereal user
pass: testAccount.pass // generated ethereal password
}
});
let senderName = req.body.senderName;
let senderEmail = req.body.senderEmail;
let subject = req.body.subject;
let message = req.body.message;
let toEmail = req.body.toEmail;
// send mail with defined transport object
let info = await transporter.sendMail({
from: `"${senderName}" <${senderEmail}>`, // sender address
to: toEmail, // receiver address
subject: subject, // Subject line
text: message, // plain text body
html: message
},function(){
res.json('Mail sent!');
});
console.log('Message sent: %s', info.messageId);
// Message sent: <b658f8ca-6296-ccf4-8306-87d57a0b4321@example.com>
// Preview only available when sending through an Ethereal account
console.log('Preview URL: %s', nodemailer.getTestMessageUrl(info));
// Preview URL: https://ethereal.email/message/WaQKMgKddxQDoou...
});
这会得到“邮件已发送!”再次响应,但服务器现在抛出此错误:UnhandledPromiseRejectionWarning:TypeError:无法读取未定义的属性“messageId”
知道我怎样才能让它工作吗?我只想要一个简单的联系表单,提交后,它会从服务器发回响应,并显示状态告诉我们邮件是否已发送。
最佳答案
你忘记添加 return ,试试这个方法:
let info = await transporter.sendMail({
from: `"${senderName}" <${senderEmail}>`, // sender address
to: toEmail, // receiver address
subject: subject, // Subject line
text: message, // plain text body
html: message
}).then((data)=>{return data}).catch((error)=> {return error});
if(info.messageId){
console.log('Message sent: %s', info.messageId);
res.json({message:'Mail sent!'});
}else{
console.log('Message Not sent');
res.json({message:'Mail not sent!'});
}
关于javascript - 使用 Nodemailer 发布 JSON 来发送电子邮件要么发送邮件,但挂起或引发错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58248612/