为什么 nodemailer 发送重复的电子邮件?

Mic*_*ael 2 javascript node.js express nodemailer

所以这是一个非常奇怪的问题,我不希望有人真正回答这个问题,但我在这里尝试看看是否有人遇到过同样的问题。

我注意到的问题是我们的应用程序似乎正在发送重复的电子邮件。例如,我可以从我们的应用程序发送一份报告,它会发送一次该电子邮件,然后看起来就像是在一分钟后发送另一封电子邮件。

我正在使用nodemailer从我们的应用程序服务器发送电子邮件,我们在办公室Outlook v16.0.12130.20272使用的默认电子邮件是使用IMAP。这些电子邮件是通过我们的noreply电子邮件发送的,我相信它是通过GoDaddy托管的。

我自己发送了测试电子邮件并查看了网络选项卡以查看它是否可能是超时问题,但响应以 a 完成200 OK status并且时间也显示为已完成。此外,当我控制台记录响应时,它只发生一次,这让我相信它实际上只发送一封电子邮件。在主机发送电子邮件和我们的收件人实际收到它们之间一定会发生一些事情,但我不太确定。

这是server.js文件。这是smtp提出请求的地方。

var nodemailer = require("nodemailer");

const path = require('path');
const express = require('express');
const http = require('http');
const fs = require('fs');
const socketIO = require('socket.io');
const bodyParser = require('body-parser')



import env from '../env.config.json';

const PORT = require('../env.config.json').SERVER.PORT;
const publicPath = path.join(__dirname, '../public');
import api from './routers/api-routing';
//---------------------------------------------------------------------------

var smtpTransport = nodemailer.createTransport({
    service: env.EMAIL.SERVICE,
    host: env.EMAIL.HOST,
    auth: {
        user:env.EMAIL.AUTH.USER,
        pass:env.EMAIL.AUTH.PASS
    }
});

var mailCounter = 0;
var numPeople = 0;

var app = express();
var server = http.createServer(app);
const port = PORT || 3000;
app.use(express.static(publicPath));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true}));

const io = socketIO(server);
app.use('/api', api(app, io));
// require('./routers/api-routing')(app, io);
//$.get("/send", { to: to, subject: subject).value, text: 'html' }, function (data) { });
app.get('*', function (request, response) {
    if (request.get('x-auth')) console.log("x-auth: ", request.get('x-auth'));
    const proto = request.get('X-Forwarded-Proto');
    if (proto) {
        if (proto === 'http') response.redirect(301, "https://ourdomain.com".concat(request.url));
    }
    response.sendFile(path.resolve(__dirname, '../', 'public', 'index.html'))
    if ((request.url).substring(0, 5) == "/send") {
        var mailOptions = {
            to: request.query.to,
            bcc: request.query.bcc,
            subject: request.query.subject,
            text: request.query.text
        }
        //console.log(mailOptions); Read up on NodeMailer for details.
        smtpTransport.sendMail({  //email options
            from: "COMPANY <noreply@ouremail.com>", // sender address.  Must be the same as authenticated user if using Gmail.
            to: mailOptions.to,
            bcc: "COMPANY <noreply@ouremail.com>",    // sending to itself
            subject: mailOptions.subject, // subject
            html: mailOptions.text, // body
        }, function (error, response) {  //callback
            if (error) {
                console.log(error);
            } else {
                console.log("Message sent");
               //console.log("Amount of people getting this email: " + response.accepted.length);
            }

            smtpTransport.close(); // shut down the connection pool, no more messages.  Comment this line out to continue sending emails.
        });
    }

});



io.on('connection', (socket) => {

    require('./middleware/sockets')(socket);


});

server.listen(port, () => {
  console.log(`Server is up on port ${port}.`);
});

Run Code Online (Sandbox Code Playgroud)

这是我们的 env.config.file 中与电子邮件相关的部分。

"EMAIL": {
    "SERVICE": "Godaddy",
    "HOST": "smtp.gmail.com",
    "AUTH": {
      "USER": "noreply@ouremail.com",
      "PASS": "OURPASS"
    }
  }

Run Code Online (Sandbox Code Playgroud)

如果有人有任何想法或建议,我将不胜感激,谢谢!

jfr*_*d00 6

您的电子邮件已上发送到你的服务器的任何请求发送,所以如果你通过浏览器访问它时,浏览器将发送两个请求,一个请求的路径,一个是favicon.ico的,当你还发送电子邮件/favicon.ico是要求。

这可能是因为您的路由处理程序配置为:

app.get('*', ...);
Run Code Online (Sandbox Code Playgroud)

这意味着无论路径如何,您都试图为每个传入的 http 请求发送电子邮件。

因此,如果您使用 浏览器访问您的主机http://yourdomain/,它将首先请求/,然后浏览器将请求/favicon.ico,从而导致您发送第二封电子邮件。

我的建议是从这个改变:

app.get('*', ...);
Run Code Online (Sandbox Code Playgroud)

对此:

app.get('/', ...);
Run Code Online (Sandbox Code Playgroud)

或者,甚至更具体,例如:

app.get('/sendemail', ...);
Run Code Online (Sandbox Code Playgroud)

因此,您仅在一个特定路径请求上发送电子邮件,并且不会发送电子邮件,而不会发送任何其他请求(例如图标)。您可能希望为任何其他路由添加通用的 express 404 处理程序。


注意:在 REST 设计中,您可能会发送带有 POST 请求而非 GET 请求的电子邮件。GET 将以只读方式检索资源,该方式不会更改任何状态,因此不会产生发送电子邮件的副作用。注意:这与您的问题完全无关,只是对典型 REST 设计的评论。