构建一个简单的表格以允许用户向我发送电子邮件。该表格会在提交时正确发送电子邮件。但是,在浏览器中刷新页面时,我还会收到一封电子邮件。是什么赋予了?我不确定问题是否在我的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 *</label>
<input id="name" name="name" type="text" placeholder="Your name" required="required">
<label for="email">Email *</label>
<input id="email" name="email" type="text" placeholder="Your email" required="required">
<label for="message">Message *</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>
答案 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 + ' <' + 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) {
// 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;
}