Node.js 使用 Nodemailer 模块发送邮件
在网站开发中,发送邮件是一个经常会遇到的需求。比如注册账号的时候,可以通过邮件来验证邮箱地址,服务变更或账号异常的时候,也可以通过邮件来通知。我的博客在回复评论的时候,也会有邮件通知。
我用来发送邮件的模块是 Nodemailer,这是一个第三方的邮件模块,也是目前使用最多的 Node.js 邮件模块。
使用 npm 安装 nodemailer:
npm install nodemailer --save
我使用的邮箱是 QQ 邮箱,使用的是 SMTP 协议。
SMTP(Simple Mail Transfer Protocol)也叫简单邮件传输协议,这是互联网上常用的一种邮件传输协议。SMTP 主要是发送邮件,不包括邮件接收。
常见邮箱的 SMTP 地址和端口
下面是一些常见邮箱的 SMTP 地址和端口:
服务商 | SMTP 地址 | SMTP 端口 |
---|---|---|
QQ邮箱 | smtp.qq.com | 25 |
网易126邮箱 | smtp.126.com | 25 |
网易163邮箱 | smtp.163.com | 25 |
新浪邮箱 | smtp.sina.cn | 25 |
Gmail | smtp.gmail.com | 465 |
雅虎邮箱 | smtp.mail.yahoo.com | 465 |
Foxmail 和 QQ邮箱的 SMTP 地址都是 smtp.qq.com
。
一般邮箱的 SMTP 服务默认都是关闭状态,你可能需要到邮箱设置中开启 SMTP。
发送文本
下面使用 Nodemailer 发送普通文本:
const nodemailer = require('nodemailer');
// 创建 SMTP 连接
const transporter = nodemailer.createTransport({
// SMTP 服务器地址
host: 'smtp.qq.com',
// 端口
port: 25,
// 使用 TLS
secure: false,
auth: {
// 你的邮箱账号或地址
user: 'i@misterma.com',
// 密码
pass: 'sjifjhierhjiji'
}
});
// 发送邮件
transporter.sendMail({
// 发信地址
from: 'i@misterma.com',
// 收信地址
to: 'misterma@gmail.com',
// 邮件标题
subject: 'Hello',
// 邮件内容(普通文本)
text: `这是来自 Mr. Ma's Blog www.misterma.com 的邮件`,
}).then(result => {
console.log(`发送成功,id:${result.messageId}`);
}).catch(error => {
console.log(error);
});
注意!在调用 createTransport
的时候,有一个选项 secure
,这是使用 TLS 连接到 SMTP 服务器。如果 SMTP 服务器的端口是 465,secure
需要设置为 true
,端口 25 和 587 secure
需要设置为 false
。
sendMail
的 to
收信地址可以设置多个,多个地址之间用英文逗号 ,
分隔。
sendMail
的发送结果会通过 Promise 的方式返回,成功的 Promise 内容如下:
{
"accepted": [
"misterma@gmail.com"
],
"rejected": [],
"ehlo": [
"PIPELINING",
"SIZE 73400320",
"AUTH LOGIN PLAIN XOAUTH XOAUTH2",
"AUTH=LOGIN",
"MAILCOMPRESS",
"8BITMIME"
],
"envelopeTime": 233,
"messageTime": 348,
"messageSize": 379,
"response": "250 OK: queued as.",
"envelope": {
"from": "i@misterma.com",
"to": [
"misterma@gmail.com"
]
},
"messageId": "<f16421d8-4658-754b-ce5b-80187d80ed0e@foxmail.com>"
}
发送 HTML
这里使用的 transporter
选项和上面是一样的,下面直接使用 sendMail
发送邮件:
// 要发送的 HTML
const htmlText = `
<h2>Mr. Ma's Blog评论回复邮件通知</h2>
<p>呵呵呵呵😀😁😂🤣</p>
`;
// 发送邮件
transporter.sendMail({
// 发信地址
from: 'i@misterma.com',
// 收信地址
to: 'misterma@gmail.com',
// 邮件标题
subject: 'Hello',
// 邮件内容(HTML)
html: htmlText
}).then(result => {
console.log(`发送成功,id:${result.messageId}`);
}).catch(error => {
console.log(error);
});
如果你要发送比较复杂的 HTML 内容,你可能需要使用 Web 模板引擎生成,关于模板引擎的使用可以看 Node.js Web 模板引擎 Eta 的简单使用 。
在发送 HTML 时,CSS 样式需要写在元素的 style
属性里,不能直接使用 link
调用 CSS 文件,也不能使用 style
标签来写 CSS。
发送附件
下面把项目目录下的 package.json
作为附件发送:
const path = require('path');
// 发送邮件
transporter.sendMail({
// 发信地址
from: 'i@misterma.com',
// 收信地址
to: 'misterma@gmail.com',
// 邮件标题
subject: 'Hello',
// 邮件内容
text: '给你发了一个 JSON 文件',
// 附件
attachments: [
{
filename: 'package.json',
path: path.join(__dirname, 'package.json')
}
]
}).then(result => {
console.log(`发送成功,id:${result.messageId}`);
});
附件 attachments
需要接收一个对象数组,下面是属性说明:
filename
:用于显示的文件名,可以和真实的文件名不一样path
:真实的文件路径content
:文件内容,可以直接使用字符串,也可以使用fs.readFile
之类的读取文件发送href
:文件的 URLhttpHeaders
:与href
一起使用的 HTTP 请求头contentType
:附件类型,省略会根据filename
自动生成cid
:附件的 Content-ID(CID),用于内联显示图片等嵌入式资源encoding
:附件内容的编码方式。默认为 base64headers
:附件的自定义标题。可以设置任何有效的 MIME 头字段和值的键值对
在发送附件的时候,path
、content
、href
一般只会选择一个。如果要发送大文件可以使用 path
,path
是流式传输的,发送动态生成的内容可以使用 content
,发送公开的网络文件可以使用 href
。
在 HTML 中插入附件图片
附件有一个 cid
属性,通过 cid
可以直接在 HTML 中显示附件图片:
const path = require('path');
// 发送邮件
transporter.sendMail({
// 发信地址
from: 'i@misterma.com',
// 收信地址
to: 'misterma@gmail.com',
// 邮件标题
subject: 'Hello',
// 邮件内容(HTML)
html: `看看这张图片 <img src="cid:www.misterma.com" alt="图片" />`,
// 附件
attachments: [
{
filename: 'test.gif',
path: path.join(__dirname, 'test.gif'),
cid: 'www.misterma.com'
}
]
}).then(result => {
console.log(`发送成功,id:${result.messageId}`);
});
附件的 cid
可以设置一个字符串,在 HTML 的 img src
可以直接使用附件 cid
,src
需要以 cid:
开头。
版权声明:本文为原创文章,版权归 Mr. Ma's Blog 所有,转载请联系博主获得授权。
本文地址:https://www.misterma.com/archives/937/
如果对本文有什么问题或疑问都可以在评论区留言,我看到后会尽量解答。