在expressjs中使用Nodemailer的正确方法是什么?

Yal*_*ber 7 node.js nodemailer

我想在expressjs应用程序中使用nodemailer.我应该继续创建路由处理程序之外的传输对象,还是在路由处理程序中创建传输对象就好了?

var express = require('express')
  , app = express()
  , nodemailer = require('nodemailer');

  smtpTrans = nodemailer.createTransport('SMTP', {
      service: 'Gmail',
      auth: {
          user: "me@gmail.com",
          pass: "application-specific-password" 
      }
  });
  app.post('/register', function(req, res){
    smtpTrans.sendMail(mailOptions);
  });
Run Code Online (Sandbox Code Playgroud)

要么

var express = require('express')
  , app = express()
  , nodemailer = require('nodemailer');

  app.post('/register', function(req, res){
    smtpTrans = nodemailer.createTransport('SMTP', {
      service: 'Gmail',
      auth: {
          user: "me@gmail.com",
          pass: "application-specific-password" 
      }
    });
    smtpTrans.sendMail(mailOptions);
  });
Run Code Online (Sandbox Code Playgroud)

Pau*_*gel 7

你必须考虑你的用例做出选择.

SMTP传输nodemailer创建一个您必须关闭的连接池.这很好,因为连接始终保持打开状态:当应用程序启动时,您只会遇到连接延迟(包括TLS协商等).

如果您发送大量消息,那么您的第一个解决方案就是好的:通过保持连接打开,您可以通过使用连接池来最小化延迟和资源利用率.

另一方面,如果您发送的消息很少,那么您的第二个解决方案是好的:如果您每小时发送一封电子邮件,则无需保持连接.请注意,因为您当前的代码有点错误:您需要显式关闭连接池.如果不这样做,即使您丢失对对象的引用,连接池也将保持打开状态.

smtpTrans = nodemailer.createTransport('SMTP', { … });
smtpTrans.sendMail(mailOptions, function (err, responseStatus) {
  smtpTrans.close(); // Don't forget to close the connection pool!
});
Run Code Online (Sandbox Code Playgroud)

这个问题的外观来看,似乎所有错误都在回调err参数中报告smtpTrans.sendMail.

编辑:这个答案是为Nodemailer 0.7编写的.1.0现在已经出局并且有一些重大变化,包括它如何处理传输和连接.有关更多信息,请参阅此博客文章.

  • Nodemailers连接池是"懒惰的",只有当有一些邮件要发送时,连接才会保持活动状态.这也意味着如果您没有显式关闭传输,那么打开SMTP连接将保持不变,直到服务器关闭这些连接不活动 - 最终达到与transport.close()相同的关闭状态.很可能你不想要未使用的连接. (2认同)
  • 所以最好在请求处理程序之外创建传输?如果我的 SMTP 服务器在任何时候关闭,它还会重新连接吗? (2认同)
  • 是的,如果发送邮件时没有可用连接,池会自动创建一个新连接。如果服务器在您尝试发送邮件的确切时刻关闭,您只会收到错误消息,否则服务器是否关闭都无关紧要。 (2认同)