依据 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. 循环文件内容进行插入换行时,如果出现逻辑错误,则传输的附件显示异常,无法正常查看和下载。

依据 smtp协议的简单golang 的发邮件实现的更多相关文章

  1. AspNetCore 目前不支持SMTP协议(基于开源组件开发邮件发送,它们分别是MailKit 和 FluentEmail )

    net所有的功能都要重新来一遍,集成众多类库,core任重道远,且发展且努力!! 我们都知道,很多的邮件发送都是基于这个SMTP协议,但现在的.net core对这方面还不太支持,所以我们选择这两个组 ...

  2. 发送邮件(遵循smtp协议即简单的邮件发送协议)

    HandleSendEmail.aspx逻辑 protected void Page_Load(object sender,EventArgs e) { foreach(var item in Req ...

  3. SMTP协议及POP3协议-邮件发送和接收原理(转)

    本文转自https://blog.csdn.net/qq_15646957/article/details/52544099 感谢作者 一. 邮件开发涉及到的一些基本概念 1.1.邮件服务器和电子邮箱 ...

  4. SMTP协议解读以及如何使用SMTP协议发送电子邮件

    电子邮件协议中POP3协议用于接收邮件,SMTP协议用于发送邮件.SMTP的全称为Simple Mail Transfer Protocol,也就是简单邮件传输协议,字如其名.   相较于POP3而言 ...

  5. python smtp 发邮件 添加附件

    # -*- coding:utf-8 -*- # __author__ = 'justing' import os import smtplib from email.mime.multipart i ...

  6. python3:利用SMTP协议发送QQ邮件+附件

    转载请表明出处:https://www.cnblogs.com/shapeL/p/9115887.html 1.发送QQ邮件,首先必须知道QQ邮箱的SMTP服务器 http://service.mai ...

  7. 设置POP3/SMTP协议 手机绑定邮箱

    例如设置企业邮箱 一.设置POP3/SMTP协议,意思是代收邮件致本地POP3接收邮件服务器:pop.qiye.qq.comSMTP发送邮件服务器:smtp.qiye.qq.com二.设置IMAP/S ...

  8. 给我发邮件(qq)| 和我联系

    qq邮箱开放平台(只能是qq对qq): 简单点的发邮件: 和我联系

  9. Smtp协议与Pop3协议的简单实现

    前言 本文主要介绍smtp与pop3协议的原理,后面会附上对其的简单封装与实现. smtp协议对应的RFC文档为:RFC821 smtp协议 SMTP(Simple Mail Transfer Pro ...

随机推荐

  1. codeforces 132C Logo Turtle(dp)

    可以用三维dp来保存状态, dp[i][j][k]表示在前i个字符变换了j步之后方向为k(k = 1 or k = 0)的最优解,也就是离原点的最大距离.这里规定0方向为正方向,1位负方向,表示的是当 ...

  2. 类似与三元表达式的 json 读取值

    需要先在项目中添加 json的dll json 序列里面的key在item.feeType里面必须存在 否则会报 未将对象引用到实例 myDr["feeType"] = Newto ...

  3. asp.net各种获取客户端ip方法

    Request.ServerVariables("REMOTE_ADDR") 来取得客户端的IP地址,但如果客户端是使用代理服务器来访问,那取到的就是代理服务器的IP地址,而不是真 ...

  4. o] TortoiseGit错误 - Could not get all refs. libgit2 returned: corrupted loose reference file

    因无法追溯的同步操作错误或工程文件错误,造成Git 同步时报错: Could not get all refs. libgit2 returned: corrupted loose reference ...

  5. Jsoup解析HTML、加载文档等实例

    一.引入jsoup的jar包:http://jsoup.org/download 补充:http://jsoup.org/apidocs/   Jsoup API    可以了解更详细的内容 二.Js ...

  6. jQuery分析(1) - 介绍

    前言 web技术高速发展到现在已经出了现非常多的库或框架,库或框架实现方法也是五花八门.现在要实现一个web站点只需要根据自己的业务需求选择js框架即可快速完成.有些框架可以快速满足业务需求,但是有些 ...

  7. 关于java中for和foreach循环

    for循环中的循环条件中的变量只求一次值!具体看最后的图片 foreach语句是java5新增,在遍历数组.集合的时候,foreach拥有不错的性能. foreach是for语句的简化,但是forea ...

  8. Linux Bash环境下单引(')、双引号(")、反引号(`)、反斜杠(\)的小结

    在bash中,$.*.?.[.].’.”.`.\.有特殊的含义.类似于编译器的预编译过程,bash在扫描命令行的过程中,会在文本层次上,优先解释所有的特殊字符,之后对转换完成的新命令行,进行内核的系统 ...

  9. Windows Phone 之播放视频

    在Windows Phone 7中播放视频有两种方式, (1)使用MediaElement 控件来播放:用MediaElement 控件来播放视频比较灵活,你需要自己去实现播放暂停进度条等等的功能,播 ...

  10. C++中数字与字符串之间的转换

    原文地址:http://www.cnblogs.com/luxiaoxun/archive/2012/08/03/2621803.html 1.字符串数字之间的转换 (1)string --> ...