美文网首页Go语言技术积累GO
使用gomail发送邮件之解决附件名乱码的问题

使用gomail发送邮件之解决附件名乱码的问题

作者: 笨鸟的巢穴 | 来源:发表于2018-11-10 22:03 被阅读31次

    在使用Go语言开发时,我们会遇到发送邮件的需求,在Go语言标准包中,也提供了邮件发送客户端smtp的封装。不过,该标准包只提供了基础的邮件发送过程,对于一些复杂的定义还需要自己去封装,封装过程就需要依据邮件协议RFC2822了。还好,github上有人专门为我们封装好了这个包:https://github.com/go-gomail/gomail。这个包封装了发送附件、图片、HTML内容模板、SSL和TLS等的支持,可以满足我们的大部分应用场景。下面,我就对gomail实现发送邮件做一下简单介绍。

    1. 需要先安装gomail

    $ go get -v gopkg.in/gomail.v2
    

    2. 导入gomail

    $ import "gopkg.in/gomail.v2"
    

    3. 需要创建一个Message实例,Message提供了整个邮件协议内容的构建,默认实例采用UTF-8字符集和Quoted-printable编码。

    对于Quoted-printable编码的定义,维基百科上是这样说的:Quoted-printable是使用可打印的ASCII字符(如字母、数字与“=”)表示各种编码格式下的字符,以便能在7-bit数据通路上传输8-bit数据, 或者更一般地说在非8-bit clean媒体上正确处理数。

    m := gomail.NewMessage()
    

    4. 构造邮件内容,包括:发件人信息、收件人、主题、内容,更多内容设定可参考协议:RFC2822

    // 发件人信息
    m.SetHeader("From", m.FormatAddress("user@example.com", "张三"))
    // 收件人
    m.SetHeader("To", "user@qq.com")
    // 主题
    m.SetHeader("Subject", "邮件标题")
    // 内容
    m.SetBody("text/html", "系统邮件请勿回复")
    

    特殊说明,构造From(发件人信息)时需要使用m.FormatAddress方法,因为发件人指定中文名或特殊字符时,需要进行编码

    5. 构造附件信息,同时对附件进行重命名

    比如,我有一个临时文件:/tmp/foo.txt,我需要将这个文件以邮件附件的方式进行发送,同时指定附件名为:附件.txt

    name := "附件.txt"
    m.Attach("/tmp/foo.txt",
        gomail.Rename(name),
    )
    

    6. 创建SMTP客户端,连接到远程的邮件服务器,需要指定服务器地址、端口号、用户名、密码,如果端口号为465的话,自动开启SSL,这个时候需要指定TLSConfig

    这里的用户名和密码指的是能够登录该邮箱的邮箱地址和密码

    d := gomail.NewDialer("smtp.example.com", 465, "user@example.com", "password")
    d.TLSConfig = &tls.Config{InsecureSkipVerify: true}
    

    7. 执行邮件发送

    err := d.DialAndSend(m)
    if err != nil {
        // 处理错误
    }
    

    至此,邮件已经发送成功了,整个邮件的内容为(其中,附件内容为foo.bar):

    Mime-Version: 1.0
    Date: Sat, 10 Nov 2018 21:40:13 +0800
    From: =?UTF-8?q?=E5=BC=A0=E4=B8=89?= <user@example.com>
    To: user@qq.com
    Subject: =?UTF-8?q?=E9=82=AE=E4=BB=B6=E6=A0=87=E9=A2=98?=
    Content-Type: multipart/mixed;
     boundary=92142f9522a20d2f4feffce957bf68b46ad1a620e68fbecbf35669266e9a
    
    --92142f9522a20d2f4feffce957bf68b46ad1a620e68fbecbf35669266e9a
    Content-Transfer-Encoding: quoted-printable
    Content-Type: text/html; charset=UTF-8
    
    =E7=B3=BB=E7=BB=9F=E9=82=AE=E4=BB=B6=E8=AF=B7=E5=8B=BF=E5=9B=9E=E5=A4=8D
    --92142f9522a20d2f4feffce957bf68b46ad1a620e68fbecbf35669266e9a
    Content-Disposition: attachment; filename="附件.txt"
    Content-Transfer-Encoding: base64
    Content-Type: text/plain; charset=utf-8; name="附件.txt"
    
    Zm9vLmJhcgo=
    --92142f9522a20d2f4feffce957bf68b46ad1a620e68fbecbf35669266e9a--
    

    打印邮件内容,可以将Message写入到一个缓冲区中,代码如下:

    buf := new(bytes.Buffer)
    m.WriteTo(buf)
    fmt.Println(buf.String())
    

    解决gomail v2.0.0版本下中文附件名乱码的问题

    在不同的邮件服务器中,对于中文附件名的编码存在不同的规范,我们可以尝试一下,将上面的邮件附件发送到QQ邮箱,附件名显示正常,发送到126的邮箱就是乱码(这是我测试的结果)。对此,我们可以通过给附件名进行编码的方式来解决这个问题。

        name := "附件.txt"
        m.Attach("/tmp/foo.txt",
            gomail.Rename(name),
            gomail.SetHeader(map[string][]string{
                "Content-Disposition": []string{
                    fmt.Sprintf(`attachment; filename="%s"`, mime.QEncoding.Encode("UTF-8", name)),
                },
            }),
        )
        
    

    将邮件内容更改为Base64编码

    
        m := gomail.NewMessage(
            gomail.SetEncoding(gomail.Base64),
        )
    
    // ...
    
    
        name := "附件.txt"
        m.Attach("/tmp/foo.txt",
            gomail.Rename(name),
            gomail.SetHeader(map[string][]string{
                "Content-Disposition": []string{
                    fmt.Sprintf(`attachment; filename="%s"`, mime.BEncoding.Encode("UTF-8", name)),
                },
            }),
        )
    
    

    使用Base64编码后的邮件内容为:

    Mime-Version: 1.0
    Date: Sat, 10 Nov 2018 21:53:22 +0800
    From: =?UTF-8?b?5byg5LiJ?= <user@example.com>
    To: user@qq.com
    Subject: =?UTF-8?b?6YKu5Lu25qCH6aKY?=
    Content-Type: multipart/mixed;
     boundary=42839966777f27ebe3861a73eabbf615036ea57b3222968e21519c64cdd5
    
    --42839966777f27ebe3861a73eabbf615036ea57b3222968e21519c64cdd5
    Content-Transfer-Encoding: base64
    Content-Type: text/html; charset=UTF-8
    
    57O757uf6YKu5Lu26K+35Yu/5Zue5aSN
    --42839966777f27ebe3861a73eabbf615036ea57b3222968e21519c64cdd5
    Content-Disposition: attachment; filename="=?UTF-8?b?6ZmE5Lu2LnR4dA==?="
    Content-Transfer-Encoding: base64
    Content-Type: text/plain; charset=utf-8; name="附件.txt"
    
    Zm9vLmJhcgo=
    --42839966777f27ebe3861a73eabbf615036ea57b3222968e21519c64cdd5--
    

    相关文章

      网友评论

        本文标题:使用gomail发送邮件之解决附件名乱码的问题

        本文链接:https://www.haomeiwen.com/subject/uzutfqtx.html