依据 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 ...
随机推荐
- java 百分比显示
DecimalFormat percent = new DecimalFormat("0.00%"); completed_num = (double) involvedTask_ ...
- 原生js日期时间插件鼠标点击文本框弹出日期时间表格选择日期时间
原文出处 (这是我从互联网上搜来的,感觉能满足各方面的需求.个人感觉挺不错的,所以后期修改了一下向大家推荐!) 效果图: html代码: <!DOCTYPE html PUBLIC " ...
- CI框架篇之模型篇--初识(1)
模型 模型是专门用来和数据库打交道的PHP类.例如,假设你想用CodeIgniter来做一个Blog. 你可以写一个模型类,里面包含插入.更新.删除Blog数据的方法. 下面的例子将向你展示一个普通的 ...
- Lucene.net项目研究说明
最近项目需要全文检索,所以找了几个开源的.NET检索项目,如:Lucene.net,Sphinx,Hubble.net.最后选择使用Lucene.ne来实现全文检索.至于原因嘛,可以参考下面几点: 1 ...
- oracle 定位热块和热链的方法
定位热链的方法 declare v_num number;begin for i in 1..1000000 loop sele ...
- Oracle学习【索引及触发器】
索引B_Tree结构 请参照 响应图例 索引是一种允许直接访问数据表中某一数据行的树形结构,为了提高查询效率而引入,是独立于表的对象,可以存放在与表不同的表空间中.索引记录中存有索引关键字和指向表中数 ...
- 制作Net程序的帮助文档--总结
一.工具的准备 目前,一般采用Sandcastle Help File Builder工具来制作.Net程序帮助文档,该工具主要是利用Xml文档里的信息以及DLL文件来生成完整的帮助文档.在Visua ...
- python模块学习 hashlib
一.hashlib概述 涉及加密服务:14. Cryptographic Services 其中 hashlib是涉及安全散列和消息摘要,提供多个不同的加密算法借口,如SHA1.SHA224.SHA2 ...
- grub2 使用memdisk工具 启动任意iso
root@zhanghua-Inspiron-:/home/zhanghua# df -h 文件系统 容量 已用 可用 已用% 挂载点 /dev/sda6 60G 12G 46G 21% / none ...
- 彻底弄清c标准库中string.h里的常用函数用法
在我们平常写的c/c++程序,一些算法题中,我们常常会用到c标准库中string.h文件中的函数,这些函数主要用于处理内存,字符串相关操作,是很有用的工具函数.而且有些时候,在笔试或面试中也会出现让你 ...