依据 smtp协议的简单golang 的发邮件实现

协议格式如下

From:sender_user@demo.net
To:to_user@demo.net
Subject:这是主题
Mime-Version:1.0 //通常是1.0
Content-Type:Multipart/mixed;Boundary="THIS_IS_BOUNDARY_JUST_MAKE_YOURS" //boundary为分界字符,跟http传文件时类似
Date:当前时间 --THIS_IS_BOUNDARY_JUST_MAKE_YOURS //boundary前边需要加上连接符 -- , 首部和第一个boundary之间有两个空行
Content-Type:text/plain;chart-set=utf-8
//单个部分的首部和正文间有个空行
这是正文1
这是正文2 --THIS_IS_BOUNDARY_JUST_MAKE_YOURS //每个部分的与上一部分之间一个空行
Content-Type:image/jpg;name="test.jpg"
Content-Transfer-Encoding:base64
Content-Description:这个是描述
//单个部分的首部和正文间有个空行
base64编码的文件 //文件内容使用base64 编码,单行不超过80字节,需要插入\r\n进行换行
--THIS_IS_BOUNDARY_JUST_MAKE_YOURS-- //最后结束的标识--boundary--

golang 代码实现如下

//email/email.go

package email

import (
"bytes"
"encoding/base64"
"fmt"
"io/ioutil"
"net/smtp"
"strings"
"time"
) //SendEmailWithAttachment : send email with attachment
func SendEmailWithAttachment(user, passwd, host, to, subject string) error {
hp := strings.Split(host, ":")
auth := smtp.PlainAuth("", user, passwd, hp[0])
buffer := bytes.NewBuffer(nil) boudary := "THIS_IS_BOUNDARY_JUST_MAKE_YOURS"
header := fmt.Sprintf("To:%s\r\n"+
"From:%s\r\n"+
"Subject:%s\r\n"+
"Content-Type:multipart/mixed;Boundary=\"%s\"\r\n"+
"Mime-Version:1.0\r\n"+
"Date:%s\r\n", to, user, subject, boudary, time.Now().String())
buffer.WriteString(header)
fmt.Print(header) msg1 := "\r\n\r\n--" + boudary + "\r\n" + "Content-Type:text/plain;charset=utf-8\r\n\r\n这是正文啊\r\n" buffer.WriteString(msg1)
fmt.Print(msg1) msg2 := fmt.Sprintf(
"\r\n--%s\r\n"+
"Content-Transfer-Encoding: base64\r\n"+
"Content-Disposition: attachment;\r\n"+
"Content-Type:image/jpg;name=\"test.jpg\"\r\n", boudary)
buffer.WriteString(msg2)
fmt.Print(msg2) attachmentBytes, err := ioutil.ReadFile("./test.jpg")
if err != nil {
fmt.Println("ReadFile ./test.jpg Error : " + err.Error())
return err
}
b := make([]byte, base64.StdEncoding.EncodedLen(len(attachmentBytes)))
base64.StdEncoding.Encode(b, attachmentBytes)
buffer.WriteString("\r\n")
fmt.Print("\r\n")
fmt.Print("图片base64编码")
for i, l := 0, len(b); i < l; i++ {
buffer.WriteByte(b[i])
if (i+1)%76 == 0 {
buffer.WriteString("\r\n")
}
} buffer.WriteString("\r\n--" + boudary + "--")
fmt.Print("\r\n--" + boudary + "--") sendto := strings.Split(to, ";")
err = smtp.SendMail(host, auth, user, sendto, buffer.Bytes()) return err
}

//email_test.go

package email

import "testing"

func TestSendEmailWithAttachment(t *testing.T) {
err := SendEmailWithAttachment("xx@example.com", "passwd", "smtp.xx.com:25", "xx@example.com", "测试附件")
if err != nil {
t.Fatal(err)
}
}

go test 打印输出如下

To:xx@example.com
From:xx@example.com
Subject:测试附件
Content-Type:multipart/mixed;Boundary="THIS_IS_BOUNDARY_JUST_MAKE_YOURS"
Mime-Version:1.0
Date:2016-09-11 12:17:37.268146477 +0800 CST --THIS_IS_BOUNDARY_JUST_MAKE_YOURS
Content-Type:text/plain;charset=utf-8 这是正文啊 --THIS_IS_BOUNDARY_JUST_MAKE_YOURS
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
Content-Type:image/jpg;name="test.jpg" 图片base64编码
--THIS_IS_BOUNDARY_JUST_MAKE_YOURS--

部分实现参考 https://github.com/scorredoira/email 具体项目中可使用该库。

遇到的问题

  1. 对boundary格式理解错误,头部写的boundary 在下边用的时候要拼上--前缀
  2. 含有附件的,第一个boundary 和 header 中间有两个空行
  3. 结束标记为 --boundary--
  4. 循环文件内容进行插入换行时,如果出现逻辑错误,则传输的附件显示异常,无法正常查看和下载。

最新文章

  1. 原生js发送ajax请求
  2. javascript基础知识-数组
  3. oralce CASE WHEN 用法
  4. Sharepoint学习笔记—习题系列--70-573习题解析 -(Q45-Q47)
  5. django在pyhton2.7 和 python3.* 之间代码和睦相处的方法
  6. Java位操作全面总结
  7. 深入学习Heritrix---解析处理器(Processor)(转)
  8. tar 命令打包,除了某个目录剩下的都打包
  9. HTML部分标签的含义
  10. java 定义mysql树形菜单
  11. 查看SQL语句执行时间与测试SQL语句性能
  12. C#_FindWindow
  13. 机器学习之分类问题实战(基于UCI Bank Marketing Dataset)
  14. Angular4---认证---使用HttpClient拦截器,解决循环依赖引用的问题
  15. [LeetCode] 2 Keys Keyboard 两键的键盘
  16. HDU 2571 命运(简单dp)
  17. 如何搜索 git 提交记录
  18. 2019年微服务5大趋势,你pick哪个?
  19. mysql 跨表更新
  20. Android——进程通信/ AIDL/Message相关知识总结贴

热门文章

  1. eAccelerator介绍
  2. sql中对查询出来的数据进行分页
  3. 微信热修复tinker及tinker server快速接入
  4. 设计webapp的新思路
  5. 完全步卸载oracle11g步骤
  6. 月薪10K必备--C#下拉框联动
  7. 生产者与消费者(二)---await与 signal
  8. [学习笔记]设计模式之Chain of Responsibility
  9. Windows Phone 之文件下载进度和速度显示
  10. Windows phone 之手势识别(Drag)