日期: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