依据 smtp协议的简单golang 的发邮件实现
依据 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 具体项目中可使用该库。
遇到的问题
- 对boundary格式理解错误,头部写的boundary 在下边用的时候要拼上--前缀
- 含有附件的,第一个boundary 和 header 中间有两个空行
- 结束标记为 --boundary--
- 循环文件内容进行插入换行时,如果出现逻辑错误,则传输的附件显示异常,无法正常查看和下载。
依据 smtp协议的简单golang 的发邮件实现的更多相关文章
- AspNetCore 目前不支持SMTP协议(基于开源组件开发邮件发送,它们分别是MailKit 和 FluentEmail )
net所有的功能都要重新来一遍,集成众多类库,core任重道远,且发展且努力!! 我们都知道,很多的邮件发送都是基于这个SMTP协议,但现在的.net core对这方面还不太支持,所以我们选择这两个组 ...
- 发送邮件(遵循smtp协议即简单的邮件发送协议)
HandleSendEmail.aspx逻辑 protected void Page_Load(object sender,EventArgs e) { foreach(var item in Req ...
- SMTP协议及POP3协议-邮件发送和接收原理(转)
本文转自https://blog.csdn.net/qq_15646957/article/details/52544099 感谢作者 一. 邮件开发涉及到的一些基本概念 1.1.邮件服务器和电子邮箱 ...
- SMTP协议解读以及如何使用SMTP协议发送电子邮件
电子邮件协议中POP3协议用于接收邮件,SMTP协议用于发送邮件.SMTP的全称为Simple Mail Transfer Protocol,也就是简单邮件传输协议,字如其名. 相较于POP3而言 ...
- python smtp 发邮件 添加附件
# -*- coding:utf-8 -*- # __author__ = 'justing' import os import smtplib from email.mime.multipart i ...
- python3:利用SMTP协议发送QQ邮件+附件
转载请表明出处:https://www.cnblogs.com/shapeL/p/9115887.html 1.发送QQ邮件,首先必须知道QQ邮箱的SMTP服务器 http://service.mai ...
- 设置POP3/SMTP协议 手机绑定邮箱
例如设置企业邮箱 一.设置POP3/SMTP协议,意思是代收邮件致本地POP3接收邮件服务器:pop.qiye.qq.comSMTP发送邮件服务器:smtp.qiye.qq.com二.设置IMAP/S ...
- 给我发邮件(qq)| 和我联系
qq邮箱开放平台(只能是qq对qq): 简单点的发邮件: 和我联系
- Smtp协议与Pop3协议的简单实现
前言 本文主要介绍smtp与pop3协议的原理,后面会附上对其的简单封装与实现. smtp协议对应的RFC文档为:RFC821 smtp协议 SMTP(Simple Mail Transfer Pro ...
随机推荐
- webapi 接口规则
[HttpPost] [AuthorizeFilter] public HttpResponseMessage DeleteStudentInfo([FromBody] object value) { ...
- 微信公众平台开发(一)——接入指南(asp.net)
第一步:申请消息接口 在公众平台网站的高级功能 – 开发模式页,点击“成为开发者”按钮,填写URL和Token,其中URL是开发者用来接收微信服务器数据的接口URL.Token可由开发者任意填写,用作 ...
- 收集SQLServer线程等待信息
要知道线程等待时间是制约SQL Server效率的重要原因,这一个随笔中将学习怎样收集SQL Server中的线程等待时间,类型等信息,这些信息是进行数据库优化的依据. sys.dm_os_wait_ ...
- JS 頁面實時更新時間
function startTime() { var today = new Date(); //定义日期对象 var yyyy = today.getFullYear(); //通过日期对象的get ...
- Tomcat源码学习记录--web服务器初步认识
Tomcat作为开源的轻量级WEB服务器,虽然不是很适合某些大型项目,但是它开源,读其源代码可以很好的提高我们的编程功底和设计思维.Tomcat中用到了很多比较好的设计模式,其中代码风格也很值得我们去 ...
- angularjs应用骨架(3)
好,继续上一章节我们继续聊聊angularjs骨架.开发任何一款优秀的应用都会面临一项非常困难的工作,那就是找到一种合适的方式方法把代码组织在合适的功能范围内.我们已经看过控制器的处理方式,它会提供一 ...
- js键盘控制div移动,解决停顿问题
问题版本代码如下: 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 <html> &l ...
- js中的prototye
前言 没事的时候写着js完,一般可能大家都知道这个属性吧,但是我还要说说,给一些不知道的人看看吧, 希望对你有帮助. 过程 以前在学c#的时候,老师最多用的就是Person这个类来开讲,我觉得是这个更 ...
- 【python】【转】 for 循环一列
Python for in循环 来源 http://c.biancheng.net/cpp/html/1822.html for..in语句是另一个循环语句,它迭代一个对象的序列,例如经历序列中的 ...
- baba 运动网
import com.sun.image.codec.jpeg.* 找不到包 在Myeclipse中编译项目时,如果提示类似 com.sun.image.codec.jpeg.* 下: imp ...