使用jszip压缩文件夹,使用nodemail发送邮件。
jszip压缩文件
压缩文件夹我们使用jszip
。官网:stuark jszip
首先在项目中安装jszip
:
1 2 3
| npm install jszip; # 或者使用yarn yarn add jszip
|
然后我们来创建一个用来测试压缩的文件夹,里面包含子文件夹:
1 2 3 4 5
| testZip ├── 1.json ├── 3.json └── innerDir └── canvas.html
|
我们希望压缩文件夹testZip
里面的所有文件夹以及文件。
首先定义一下路径:
1 2 3 4 5 6 7 8 9
| const fs = require('fs') const path = require('path') const JSZIP = require('jszip')
const dirPath = path.resolve(__dirname, 'testZip');
const name = 'testZip';
const zipPath = path.resolve(__dirname, './');
|
然后我们规划下方法,我们需要一个压缩方法,期望传递的是目标文件夹的路径、压缩包的名称、生成压缩包后的存放路径:
1 2 3
| function compressedDir(dirPath, name, zipPath) {
}
|
我们是要压缩一个文件夹,这个文件夹里面可能包含着文件和文件夹,所以我们需要递归读取文件夹。
- 遇到文件夹里面的文件夹的话,需要使用
zip.folder()
给压缩包创建文件夹,然后进入文件夹继续读取。
- 遇到文件的话,直接使用
zip.file()
来放入压缩包中
然后我们有如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
function readDirDeep(zip, dirPath) { const files = fs.readdirSync(dirPath); for (const fileName of files) { const filePath = path.join(dirPath, fileName); const stat = fs.statSync(filePath); if (!stat.isDirectory()) { zip.file(fileName, fs.readFileSync(filePath)); continue; } const folderZip = zip.folder(fileName); readDirDeep(folderZip, filePath); } }
|
然后开始继续完善compressedDir
方法。
我们需要考虑一下几点:
- 判断传递的路径,
- 如果是非文件夹,那么就直接放入压缩包即可。
- 如果是文件夹,调用
readDirDeep
来递归读取。
- 将读取好的zip对象调用
zip.generateAsync()
函数进行压缩包文件流的创建。
- 将压缩包的流内容写入存储压缩包的路径,获得压缩包文件,结束。
我们有如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
async function compressedDir(dirPath, name, zipDir = null ) { if (!zipDir) { zipDir = path.resolve(__dirname, './'); } const zip = new JSZIP(); const stat = fs.statSync(dirPath); if (!stat.isDirectory()) { console.log(path.parse(dirPath)) const {base: fileName = 'unKnow'} = path.parse(dirPath); zip.file(fileName, fs.readFileSync(dirPath)); } else { readDirDeep(zip, dirPath) } const zipContent = await zip.generateAsync({ type: 'nodebuffer', compression: 'DEFLATE', compressionOptions: { level: 9, } }); const zipPath = path.join(zipDir, `${name}.zip`); fs.writeFileSync(zipPath, zipContent, 'utf-8') return zipPath; }
|
然后来运行一个例子进行测试:
1 2 3 4 5 6 7 8 9 10
| try { const dirPath = path.resolve(__dirname, 'testZip'); const name = 'testZip'; const zipDir= path.resolve(__dirname, './'); compressedDir(dirPath, name,zipDir).then(zipPath => { console.log('压缩完成,路径为:', zipPath) }); } catch (e) { console.log(e); }
|
然后检查是否正确生成了对应的zip文件,并且需要解压缩zip看看里面的内容是否正常。
发送邮件
发送邮件我们使用nodemailer
,官网:nodemailer
安装:
1 2 3
| npm install nodemailer # 或使用yarn yarn add nodemailer
|
首先我们需要一个传输器对象:
1 2 3 4
| const nodemailer = require('nodemailer') const fs = require('fs')
const transporter = nodemailer.createTransport(options)
|
在使用传输器前我们需要了解下SMTP(Simple Mail Transfer Protocol)协议。参考:维基百科 SMTP
几乎每个电子邮件提供商都支持基于SMTP协议的邮件发送。nodemailer
中主要的传输方式就是SMTP协议。
SMTP是一个”推送“协议,它不允许根据需要从远程服务器上”拉取“消息。要拉取消息到客户端,邮件客户端必须使用POP3或IMAP。
所以我们主要使用SMTP来发送邮件。
我们来看下创建传输器的时候需要啥:
- port 端口
- host 主机
- auth 身份验证
- secure 是否使用TLS,如果端口是465,需要设置为true;如果是587或25,就设置为false
我这里使用网易的126邮箱。它在邮箱的设置那里有SMTP的设置,并可以提供客户端授权密码,这样可以随时取消授权,也不会暴露我邮箱本来的密码,非常nice。
我们在126邮箱的设置 -> POP3/SMTP/IMAP
开启SMTP服务。并在授权管理
这里设置授权密码。
服务器地址:smtp.126.com
。安全上是支持SSL链接的,所以端口的话是465
。
然后回到代码,我们创建传输器:
1 2 3 4 5 6 7 8 9 10 11 12 13
| const nodemailer = require('nodemailer') const fs = require('fs')
const transporter = nodemailer.createTransport({ host: 'smtp.126.com', secure: true, port: 465, auth: { user: 'tonycs_y@126.com', pass: 'xxx' } })
|
然后封装方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| async function sendMail({ // 邮件标题 subject, // 邮件内容 text, // 文件 attachments }) { const message = { from: '"tonycs" <tonycs_y@126.com>', to: 'target@mail.com', subject, text, html: text, attachments, } const info = await transporter.sendMail(message) console.log(`--- 邮件发送成功 ✅ ${info.messageId}`); }
|
这里主要说下附件的参数,我们可以将附件的路径转换为文件流,传递给attachments
。需要注意的是,这里附件的名称是小写的filename
。
调用这个方法:
1 2 3 4 5 6 7 8
| sendMail({ subject: `测试邮件`, text: `邮件正文`, attachments: { filename: `附件.zip`, content: fs.createReadStream(zipPath) } }).then();
|
然后查看目标邮箱中是否有对应的邮件。
完成了这个流程,我们就可以很容易的构造一个备份脚本。将对应数据存入本地的文件夹,然后压缩文件夹,再以附件的形式发送邮件,一步到位。