1. 前言
最近在写一个博客系统,在「评论」模块中,有这样一个需求:有用户1已经评论留言,用户2在用户1的评论下,给用户1回复评论。
这时候需要发一封邮件通知用户1的评论收到了回复,所以就想写一个自动发邮件的功能。
在网上找到了「Nodemailer」这个项目,「Nodemailer」是一个简单易用的Node.js
邮件发送组件,可以使用SMTP协议,用指定的账户发送电子邮件。
但是「Nodemailer」只能运行在Node.js
环境中,在浏览器中直接使用会报错,使用不了。所以我的想法是,在自己的「阿里云服务器」Node.js
环境中,使用express
框架搭建一个简单的路由,「Nodemailer」运行在服务器上。在前端页面利用Axios
发送http请求,服务器收到相应请求后,获取参数,使用「Nodemailer」发送电子邮件。
同时还要注意同源政策的问题。
话不多说,开始实现这样一个功能吧!
2. 客户端代码
客户端只需要通过Axios
发送http请求给服务器即可:
axios({
url: 'http://XX.XXX.XXX.XXX:4000/email',
method: 'get',
params: {
name,
owner,
email: replyEmail,
search: 'msg',
},
withCredentials: true,
})
.then(() => message.success('回复成功!'))
.catch(err => console.error(err));
这里设置了withCredentials
为true
,指定在涉及到跨域请求时,携带cookie
信息。
3. 服务端代码
使用模块化路由,所有的路由请求都在app.js
中处理,各个模块处理相应的逻辑。
在app.js
中,使用use()
中间件拦截所有请求,为res
统一设置header
,解决同源限制问题。
app.js
:
const express = require('express');
const app = express();
const email = require('./email');
// 拦截所有请求
app.use((req, res, next) => {
// 1.允许哪些客户端访问我
// * 代表允许所有的客户端访问我
// 注意:如果跨域请求中涉及到cookie信息传递,值不可以为*号 比如是具体的域名信息
res.header('Access-Control-Allow-Origin', 'http://localhost:3001');
// 2.允许客户端使用哪些请求方法访问我
res.header('Access-Control-Allow-Methods', 'get,post');
// 允许客户端发送跨域请求时携带cookie信息
res.header('Access-Control-Allow-Credentials', true);
next();
});
// 博客评论收到回复后的邮件提醒服务
app.use('/email', email);
app.listen(4000);
console.log('服务器启动成功,监听4000端口...');
发送电子邮件的步骤写在email.js
中,主要分为三步:
- 引入
nodemailer
- 创建发件人的信息
- 发送电子邮件
这里我使用的是163邮箱,需要在163邮箱中,开启smtp
服务,并获取到授权码。
email.js
:
const express = require('express');
const email = express.Router();
// 1. 引入nodemailer
const nodemailer = require('nodemailer');
// 2. 创建发件人的信息
const transporter = nodemailer.createTransport({
host: 'smtp.163.com',
port: 465,
secureConnection: true, // use SSL
auth: {
user: 'lzxjack1998@163.com', // 自己的邮箱地址
pass: 'xxxxxxxxxxxxxx', // 不是密码,是授权码
},
});
email.get('/', (req, res) => {
const { name, owner, email: to, search } = req.query;
const blogUrl = 'xxxxxxxxxxxxxxxxx';
const html = 'xxxxxxxxxxxxxx';
const subject = '评论回复提醒';
const from = '"飞鸟"<lzxjack1998@163.com>';
const mailOptions = {
from, // 发件人
to, // 收件人
subject, // 邮件标题
html, // 邮件内容,html格式
};
// 3. 发送电子邮件
transporter.sendMail(mailOptions, (error, info) => {
if (error) return console.log(error);
console.log(info);
});
res.send('已成功发送邮件!');
});
module.exports = email;
4. 发送邮件
将服务端代码放到云服务器上,运行app.js
:
尝试回复一个评论,发送axios
请求,发送电子邮件,服务端打印相关信息:
成功收到邮件!