依据 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) { ...
- android应用一(调用WebServices)
搞了一个月的android,现学现卖,终于还是搞完了,停下来,整理思路,写写记录吧. 我们知道android访问远程数据库主要有两种协议,一种是SOAP,另外一种就是HTTP.而我们再看看WebSer ...
- 手势识别=读取手机联系人=ContentResolver-Day3
手势识别=读取手机联系人=ContentResolverDay32 mobile3.0 手机设置向导页面完成 选择器没有做完成 样式提取完成 自定义控件的优化继续 抽取父类Activity 完成 手机 ...
- java - import *
以前看过很多视频,现在发觉很多讲师讲的有些地方是错的,在这里就说一下 import *,例如: import java.util.*的时候,表示的是将文件中使用到的类(而不是全部类)导入,例如在imp ...
- hibernate 连接 oracle数据库
前言:以下所有的操作都是基于你已经成功安装了oracle数据库并且java的开发环境正常的情况下进行的. 如果没有完善请先配置基础环境. 第一步:配置需要的环境(下载并导入需要的包). 我的百度云盘里 ...
- Java--获取request中所有参数的方法
我们通常用到request获取某个参数的方法: String value=request.getparameter("key"); 如果想要获取request中所有的参数呢? re ...
- MyBatis的学习总结四:实现关联表查询【参考】
一.一对一的表关联查询(edi_test_task 和 edi_task_detail) 例子:一条任务明细对一条任务记录 对应的sql的映射xml文件如下: <?xml version=& ...
- iOS 使用GBK编码的hmacMD5算法
该方法是写在工具类中的,而不是写在NSString的类别中 方法的声明: /** * 使用hmac-md5加密 * * @param clearText 原文 * @param secret ...
- 比较ArrayList和LinkedList
比较一:添加内容 涉及方法:add public void add_test(){ List<Person> addlist = new ArrayList<Person>() ...
- Spring MVC 3.2 406 Not Acceptable
Spring MVC 3.2 406 Not Acceptable 这个报错主要是因为SpringMVC配置文件配置问题. 修改步骤如下: 首先,修改spring-mvc.xsd为 spring-mv ...