Nodemailer应用程序在页面刷新时发送电子邮件

时间:2018-09-12 02:18:43

标签: javascript html node.js nodemailer

构建一个简单的表格以允许用户向我发送电子邮件。该表格会在提交时正确发送电子邮件。但是,在浏览器中刷新页面时,我还会收到一封电子邮件。是什么赋予了?我不确定问题是否在我的server.js文件或index.ejs中。页面加载时是否触发了submit按钮?

这是server.js文件:

var express = require('express'),
    path = require('path'),
    nodeMailer = require('nodemailer'),
    bodyParser = require('body-parser');

    var app = express();
    app.set('view engine', 'ejs');
    app.use(express.static(__dirname));
    app.use(bodyParser.urlencoded({extended: true}));
    app.use(bodyParser.json());
    var port = 3000;
    app.get('/', function (req, res) {
      res.render('index');
    });
    app.post('/contact', function (req, res) {
      let transporter = nodeMailer.createTransport({
          host: 'smtp.gmail.com',
          port: 465,
          secure: true,
          auth: {
              user: '****@gmail.com',
              pass: '****'
          }
      });
      let mailOptions = {
          from: req.body.name + ' <' + req.body.email + '>', // sender address
          to: '****@gmail.com', // list of receivers
          subject: 'New message test', // Subject line
          text: `${req.body.name} (${req.body.email}) says: ${req.body.message}`, // plain text body
          html: '<b>Email Test</b>' // html body
      };

      transporter.sendMail(mailOptions, (error, info) => {
          if (error) {
              return console.log(error);
          }
          console.log('Message %s sent: %s', info.messageId, info.response);
              res.render('index');
          });
      });
          app.listen(port, function(){
            console.log('Server is running at port: ',port);
          });

还有index.ejs:

<!doctype html>
<html class="no-js" lang="">

<head>
  <meta charset="utf-8">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  <title></title>
  <meta name="description" content="">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

</head>

<body>
  <form action="/contact" id="contact-form" method="post" role="form">
    <fieldset>
      <label for="name">Name &#42;</label>
      <input id="name" name="name" type="text" placeholder="Your name" required="required">
      <label for="email">Email &#42;</label>
      <input id="email" name="email" type="text" placeholder="Your email" required="required">
      <label for="message">Message &#42;</label>
      <textarea id="message" name="message" placeholder="Enter your message here" rows="3" required="required"></textarea>
      <button type="submit">Submit</button>
    </fieldset>
  </form>
</body>
</html>

2 个答案:

答案 0 :(得分:0)

如果您打开路线/它会立即发送电子邮件?

答案 1 :(得分:0)

这是浏览器的属性,在首次提交<FORM>后,每次刷新时,都会发送相同的请求。

为什么?由于您的下一页是您在上一页中执行的操作的结果,因此请检查您在浏览器上的网址已更改为localhost:3000/contact,这不是GET方法,而是帖子,因为您呈现了POST呼叫中的页面。即使会渲染不同的ejs,也会在refresh上发送对POST: contact的相同调用。

唯一的解决方案是使用single-page application

示例

server.js

```

var express = require('express'),
path = require('path'),
nodeMailer = require('nodemailer'),
bodyParser = require('body-parser');

var app = express();
app.set('view engine', 'ejs');
app.use(express.static(__dirname));
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
var port = 3000;
app.get('/', function (req, res) {
  res.render('index');
});

app.post('/contact', function (req, res) {
  let transporter = nodeMailer.createTransport({
      host: 'smtp.gmail.com',
      port: 465,
      secure: true,
      auth: {
          user: '****@gmail.com',
          pass: '****'
      }
  });
  let mailOptions = {
      from: req.body.name + ' &lt;' + req.body.email + '&gt;', // sender address
      to: '****@gmail.com', // list of receivers
      subject: 'New message test', // Subject line
      text: `${req.body.name} (${req.body.email}) says: ${req.body.message}`, // plain text body
      html: '<b>Email Test</b>' // html body
  };

  transporter.sendMail(mailOptions, (error, info) => {
      if (error) {

          // Send Response back to caller
          res.status(400).send(error);
      }
      console.log('Message %s sent: %s', info.messageId, info.response);
          res.status(200).send('Success');
      });
  });
      app.listen(port, function(){
        console.log('Server is running at port: ',port);
      });

`

HTML / EJS:

<!DOCTYPE html>
<html >
    <head>
        <meta charset="UTF-8">    
        <link rel="stylesheet" type="text/css" href="/css/bootstrap.min.css" />
        <link rel="stylesheet" type="text/css" href="/css/app.css" />
        <link rel="icon" href="logo.jpg" />
        <title>Send Mail</title>
    </head>
    <body>
        <div class="col-md-6 offset-md-3">

            <!-- No need for `form` as will use JavaScript for Single Page Application -->
            <div id="sendMail" class="hide">
                <div class="col-md-12 form-group">
                    <label for="email">Email:</label>
                    <input id="email" class="form-control" type="email">
                    <span id="emailError" class="hide error">Valid Email Required</span>
                </div>
                <div class="col-md-12 form-group">
                    <label for="name">First Name:</label>
                    <input id="name" class="form-control" type="text">
                    <span id="nameError" class="hide error">Valid First Name Required</span>
                </div>
                <div class="col-md-12 form-group">
                    <label for="message">Message :</label>
                    <textarea id="message" class="form-control" type="text"></textarea>
                    <span id="meggageError" class="hide error">Valid Last Name Required</span>
                </div>
                <div class="col-md-12 form-group">
                    <p class="btn btn-primary form-control" onclick="sendMail()">Submit</p>
                </div>
            </div>
        </div>
        <script type="text/javascript" src="/js/jquery.min.js"></script>
        <!-- `login.js` is only used in `login.ejs` -->
        <script type="text/javascript" src="/js/sendMail.js"></script>
        <script type="text/javascript" src="/js/service.js"></script>
    </body>
</html>

sendMail.js

"use strict";

function sendMail() {
    // JavaScript uses `id` to fetch value
    let email               = $("#email").val(),
        name                = $("#name").val(),
        message             = $("#addLname").val();

    // Show error `span` when email is invalid
    if ( validateEmail(email) ) {
        $("#emailError").addClass("hide");
    } else {
        $("#emailError").removeClass("hide");
        return;
    }

    // Show error `span` when First Name is invalid
    if ( validateFname(fName) ) {
        $("#nameError").addClass("hide");
    } else {
        $("#nameError").removeClass("hide");
        return;
    }

    // Show error `span` when Last Name is invalid
    if ( message ) {
        $("#messageError").addClass("hide");
    } else {
        $("#messageError").removeClass("hide");
        return;
    }

    // Calling local API to set authentication
    // Everything in public is visible for hackers
    // Thus to hide auth calling local backend
    $.ajax({
        "url": "/contact",
        "method": "POST",
        "data": {email, name, message}
    })
    .then( result => {
        // On success empty all the input fields.
        $("#email").val('');
        $("#name").val('');
        $("#message").val('');

        // Message to notify success submition
        alert("Successfully Send Mail.");
        return;
    })
    .catch( err => {
        // Notify in case some error occured
        alert("An error occured.");
        return;
    });
}

service.js

"use strict";

/**
 * Common services used by all the other scripts
 * All these are generic functions
 *  
*/

// Validate Email based upon pattern
function validateEmail (email) {
    if ( email && email.match(/^([A-Za-z0-9]{2,})([@]{1})([A-z]{1,})([.]{1})([A-z.]{1,})*$/) ) {
        return true;
    }
    return false;
}

// Validate First Name based upon pattern
function validateName (name) {
    if ( name && name.match(/^([A-Za-z]{2,})*$/) ) {
        return true;
    }
    return false;
}