日期:2019年12月30日
阿里云邮箱企业版通过 SMTP 的方式发送带附件的邮件的方法就是:构建一封 MIME 格式的邮件内容。
MIME 基础知识
-
MIME 表示多用途 Internet 邮件扩允协议。MIME 扩允了基本的面向文本的 Internet 邮件系统,以便可以在消息中包含二进制附件。
-
MIME 信息由正常的 Internet 文本邮件组成,文本邮件拥有符合 RFC 2822/5322 的信息头和格式化过的信息体。
-
MIME 协议的 RFC 地址:https://www.ietf.org/rfc/rfc2045.txt 。
MIME 信息剖析
一封普通的文本邮件的信息包含一个头部分(例如:From、To、Subject 等等)和一个体部分。体部分通常为单体类型(例如:text、image、audio、video、application 等等)或是复合类型(即:multipart)。头部分和体部分之间用一个空行进行分隔,并且体部分的类型由信头内容类型字段 Content-Type 描述。
- 信头含义 (Headers)
域名 | 含义 |
---|---|
Received | 传输路径 |
Return-Path | 回复地址 |
Delivered-To | 发送地址 |
Reply-To | 回复地址 |
From | 发件人地址 |
To | 收件人地址 |
Cc | 抄送地址 |
Bcc | 暗送地址 |
Date | 日期和时间 |
Subject | 主题 |
Message-ID | 消息 ID |
MIME-Version | MIME 版本 |
Content-Type | 内容的类型 |
Content-Transfer-Encoding | 内容的传输编码方式 |
-
内容类型(Content-Type),表现形式为:Content-Type: [type]/[subtype]。
其中 type 的形式为:text:用于标准化地表示的文本信息,文本消息可以是多种字符集和或者多种格式的。
Image:用于传输静态图片数据。
Audio:用于传输音频或者音声数据。
Video:用于传输动态影像数据,可以是与音频编辑在一起的视频数据格式。
Application:用于传输应用程序数据或者二进制数据。
Message:用于包装一个 E-mail 消息。
Multipart:用于连接消息体的多个部分构成一个消息,这些部分可以是不同类型的数据。其中 subtype 用于指定 type 的详细形式,常用的 subtype 如下所示:text/plain(纯文本)
text/html(HTML 文档)
application/xhtml+xml(XHTML 文档)
image/gif(GIF 图像)
image/jpeg(JPEG 图像)
image/png(PNG 图像)
video/mpeg(MPEG 动画)
application/octet-stream(任意的二进制数据)
message/rfc822(RFC 822 形式)
multipart/alternative(HTML 邮件的 HTML 形式和纯文本形式,相同内容使用不同形式表示。) -
内容传输编码(Content-Transfer-Encoding),指定内容区域使用的字符编码方式。通常为:7bit,8bit,binary,quoted-printable,base64。
MIME 的信体部分
-
邮件中常见的简单类型有 text/plain(纯文本)和 text/html(超文本)。
-
复杂的邮件内容格式采用 multipart 类型,可以包括纯文本/超文本、内嵌资源(图片)、附件类型等等。
multipart 类型的邮件体被分为多个段,每个段又包含段头和段体两部分,这两部分之间也以空行分隔。
段头含义:
域名 | 含义 |
---|---|
Content-Type | 段体的类型 |
Content-Transfer-Encoding | 段体的传输编码方式 |
Content-Disposition | 段体的安排方式 |
Content-ID | 段体的 ID |
Content-Location | 段体的位置(路径) |
Content-Base | 段体的基位置 |
常见的 multipart 类型有三种:multipart/mixed, multipart/related 和 multipart/alternative。
复合类型层次关系示例图:
multipart 诸类型的共同特征是,在段头指定 boundary 参数字符串,段体内的每个子段以此字符串定界。所有的子段都以 —boundary 行开始,父段则以 —boundary— 行结束。段与段之间也以空行分隔。
注意:
附件邮件总大小不超过15M,一次最多不超过100个附件。
代码示例(python)
-
# -*- coding:utf-8 -*-
-
-
import urllib, urllib2
-
import smtplib
-
from email.mime.multipart import MIMEMultipart
-
from email.mime.text import MIMEText
-
from email.mime.application import MIMEApplication
-
-
# 发件人地址,通过控制台创建的发件人地址
-
username = 'xxx@xxx.com'
-
# 发件人密码,通过控制台创建的发件人密码
-
password = 'XXXXXXXX'
-
-
# 收件人地址列表,支持多个收件人,最多30个
-
rcptlist = ['to1@to.com', 'to2@to.com']
-
receivers = ','.join(rcptlist)
-
-
# 构建 multipart 的邮件消息
-
msg = MIMEMultipart('mixed')
-
msg['Subject'] = 'Test Email'
-
msg['From'] = username
-
msg['To'] = receivers
-
-
# 构建 multipart/alternative 的 text/plain 部分
-
alternative = MIMEMultipart('alternative')
-
textplain = MIMEText('纯文本部分', _subtype='plain', _charset='UTF-8')
-
alternative.attach(textplain)
-
-
# 构建 multipart/alternative 的 text/html 部分
-
texthtml = MIMEText('超文本部分', _subtype='html', _charset='UTF-8')
-
alternative.attach(texthtml)
-
-
# 将 alternative 加入 mixed 的内部
-
msg.attach(alternative)
-
-
# 附件类型
-
# xlsx 类型的附件
-
xlsxpart = MIMEApplication(open('测试文件1.xlsx', 'rb').read())
-
xlsxpart.add_header('Content-Disposition', 'attachment', filename=Header("测试文件1.xlsx","utf-8").encode())
-
msg.attach(xlsxpart)
-
-
# jpg 类型的附件
-
jpgpart = MIMEApplication(open