你学废了吗: node发送邮件

背景

因为每天都需要发送工作日志,所以我决定做个快速发送邮件的工具,就用node写了个发邮件的功能,然后就有了这篇文章。

NODEMAILER

nodemailer是node的一个插件,用于发送邮件,也是应用最广泛的node邮件模块。官网:nodemailer.com

安装使用

安装

首先安装插件:

shell 复制代码
npm install nodemailer -S

发送邮件

第一步,创建一个邮件传输对象:

js 复制代码
let transporter = nodemailer.createTransport(transport[, defaults]);

参数说明:

  • transport 传输配置对象,主要是邮件相关的配置,包括邮件服务的配置、鉴权配置、插件对象等等
  • defaults 邮件配置的默认值对象,默认配置会合并到每个消息对象中的对象,可以通过默认对象为没封邮件添加共享配置。

第二步,使用传输对象发布邮件:

js 复制代码
transporter.sendMail(data[, callback]);

参数说明:

  • data 邮件内容对象,包括发件人、收件人、抄送人、标题、内容、附件等等,具体内容查看:nodemailer.com/message/
  • callback 回调方法,包含两个参数
    • err 发送失败时返回的对象,包含错误的详情
    • info 发送结果,使用不用的传送机制会返回不同格式的内容。基本上会包含以下内容:
      • messageId 邮件服务器为邮件颁发的唯一的消息标识
      • envelope 邮件信封对象(发件人、收件人、抄送人、秘密抄送人等)
      • accepted SMTP传输返回的接受的收件人地址的数组
      • rejected SMTP传输返回的被拒绝的收件人地址的数组
      • pending SMTP传输返回的暂时被拒绝的收件人地址以及服务器的响应的数组
      • response SMTP传输机制返回的字符串,服务器的最后一个SMTP相应

有两个点需要注意:

  • 如果有多个收件人,只要有一个收件人接受了邮件,该邮件就被视为已发送
  • 如果没有传入callback,sendMail会返回一个promise对象

示例

js 复制代码
// 创建传输对象
let transport = nodeMailer.createTransport(
  {
      host: 'smtp.163.com',  // SMTP传输
      port: 465,
      secure: true, // use TLS
    }, 
    {
       auth: {
        user: 'xxxx', // 账号
        pass: '1111'  // 密码
      }
    }
);

// 发送邮件
transport.sendMail(
  {
    from: 'xxx', // 发件人
    to: 'xxxxxx,xxxxx',  // 收件人,多个收件人可以用,或;分割也可以传入数组
    subject: 'title',
    html: ` 
    <style type="text/css">
      .list  {
        color: #ff0000;
      }
    </style>
    <div class="list">
      测试测试
    </div>
    `
  }, 
  (err, info) => {
    if (err) {
      console.error('发送失败', err);
    }

    console.log('发送信息', info);
  }
);

使用传输机制

邮件系统

一个邮件系统基本包括以下五个部分:

  • 用户代理(User Agent),邮件的界面系统,主要为用户提供接收、发送、编辑、管理邮件的能力,主要是指邮件客户端(Foxmail、Outlook)
  • 传输代理(Message Transfer Agent),负责邮件的传输和路由,将邮件从发件人传递到收件人的过程中可能会经过多个中间服务器,代理会根据收件人地址的域名来确认跳转的路径。
  • 邮件服务器(Mail Server),邮件服务商提供的存储和管理邮件的服务器,负责接受、发送、存储邮件。邮件服务器会会使用标准邮件传输协议来与用户代理和传输代理进行通讯。分别会从传输代理接收邮件,并存储到对应用户的邮箱;从用户代理接收要发送的邮件并转发给传输代理。
  • 邮件协议(Mail Protocols),定义了邮件系统中不同组件之间的通信规则和格式。
  • 邮件存储系统(Mail Store System),邮件存储系统用于存储和管理电子邮件的实际数据。它可以是基于文件的存储系统,也可以是基于数据库的存储系统。

邮件协议

电子邮件需要在互联网上传递,协议规范了不同的计算机和邮件服务间的传输和交流的标准。它定义了邮件的格式、传输方式以及各个参与方之间的通信规则。这些协议包括:SMTP(Simple Mail Transfer Protocol)(简单邮件传输协议)POP3(Post Office Protocol 3)(邮局协议第三版)IMAP(Internet Mail Access Protocol)(互联网邮件存取协议)

SMTP协议

全称 Simple Mail Transfer Protocol (简单邮件传输协议),该协议用于邮件发送,定义了邮件传输的规范。当发件人发送一封电子邮件时,SMTP协议负责将邮件从发件人的计算机发送到目标计算机。在这过程中它通过TCP/IP来确保邮件能够准确的传输,并且在发送和中转过程中为邮件确认下一个目标地址。 值得注意的是:SMTP协议只负责发送邮件,不负责接收邮件,这跟我们常接触的协议有比较大的区别。

POP3协议

全称 Post Office Protocol 3(邮局协议第三版),该协议用于邮件的接收。它允许用户从远程邮件服务器上下载邮件到本地计算机,以便离线阅读和管理邮件。POP3是比较老的协议,有比较多的局限性,例如只支持文本邮件、不支持文件夹等,而且还有一个默认行为:将邮件下载到本地后就会把服务端的邮件删除掉(除了有特殊标记的邮件外)。这种"下载并删除"的行为会导致邮件只有本地副本,安全性和可用性一般。

IMAP协议

全称 Internet Mail Access Protocol(互联网邮件存取协议),该协议用于邮件的接收,与POP3类似。它允许客户端通过远程的方式(不需要下载邮件到本地)直接在服务器上管理邮件,支持增删改、搜索、文件夹/文件管理等。由于是online的模式,可以再多个设备间同步。

通信过程

以下是一个简化的邮件通信图:

WebMail

上面所述的是传统的邮件系统,用户通过UA来完成邮件相关的操作。而WebMail则更简单,不需要安装UA,直接浏览器打开(163邮箱、QQ邮箱),web端可以通过http与服务器进行通讯,当然邮件服务器之间还是通过SMTP来传递邮件。

使用SMTP发送邮件

ok,了解了邮件系统的基本情况,就知道要干什么了。因为只需要发送邮件的功能,所以只要实现SMTP发送即可。 首先,打开邮箱的SMTP服务,这个在各邮箱的设置中可以配置。

然后,开始撸码,为了方便后续使用,做个简单的封装:

js 复制代码
const nodeMailer = require('nodemailer');

class EmailSmtpSender {
  transport = null;
  smtpConfig = {
    host: '',
    port: '',
    secure: true,
    auth: {
      user: '',
      pass: ''
    }
  };

  constructor(host, port, user, pass) {
    if (!host || !port || !user || !pass) {
      throw new Error('smtp配置不能为空');
    }

    this.smtpConfig = {
      host,
      port,
      secure: true,
      auth: {
        user,
        pass
      }
    };
    
    this.transport = nodeMailer.createTransport(this.smtpConfig);
  }

  sendTextEmail(to, subject, text) {
    return this.send(to, { subject, text });
  }

  sendHtmlEmail(to, subject, html) {
    return this.send(to, { subject, html });
  }

  async send(to, config) { 
    const from = this.smtpConfig.auth.user;
   
    return await this.transport.sendMail(
      {
        from,
        to,
        ...config
      }
    );
  }
}

module.exports = EmailSmtpSender;

引入使用:

js 复制代码
const EmailSmtpSender = require('./email-smtp-sender');

const sender = new EmailSmtpSender('smtp.163.com', 465, 'xxxxx', 'xxxxx');

sender.sendTextEmail('xxxxx', 'text', '123123123213123').then(() => {
  console.log('send text email success');
});

sender.sendHtmlEmail('xxxxxx', 'text html', '<div style="color:#ff0000;">45ewerwerwerwe</div>').then(() => {
  console.log('send html email success');
});

总结

本文对nodemailer的使用做了浅显的总结,顺便聊了下邮件系统和协议。当然nodemailer的功能很多,如果有需要可以继续探索。

相关推荐
多多*23 分钟前
Spring之Bean的初始化 Bean的生命周期 全站式解析
java·开发语言·前端·数据库·后端·spring·servlet
linweidong28 分钟前
在企业级应用中,你如何构建一个全面的前端测试策略,包括单元测试、集成测试、端到端测试
前端·selenium·单元测试·集成测试·前端面试·mocha·前端面经
满怀10151 小时前
【HTML 全栈进阶】从语义化到现代 Web 开发实战
前端·html
东锋1.31 小时前
前端动画库 Anime.js 的V4 版本,兼容 Vue、React
前端·javascript·vue.js
满怀10151 小时前
【Flask全栈开发指南】从零构建企业级Web应用
前端·python·flask·后端开发·全栈开发
小杨升级打怪中2 小时前
前端面经-webpack篇--定义、配置、构建流程、 Loader、Tree Shaking、懒加载与预加载、代码分割、 Plugin 机制
前端·webpack·node.js
Yvonne爱编码2 小时前
CSS- 4.4 固定定位(fixed)& 咖啡售卖官网实例
前端·css·html·状态模式·hbuilder
SuperherRo2 小时前
Web开发-JavaEE应用&SpringBoot栈&SnakeYaml反序列化链&JAR&WAR&构建打包
前端·java-ee·jar·反序列化·war·snakeyaml
大帅不是我2 小时前
Python多进程编程执行任务
java·前端·python
前端怎么个事2 小时前
框架的源码理解——V3中的ref和reactive
前端·javascript·vue.js