SMTP 中带有纯文本、HTML 和附件的电子邮件的正确电子邮件格式?

Posted

技术标签:

【中文标题】SMTP 中带有纯文本、HTML 和附件的电子邮件的正确电子邮件格式?【英文标题】:Correct email format for Email with Plain, HTML and an Attachment in SMTP? 【发布时间】:2012-06-08 01:14:40 【问题描述】:

问题:

我尝试复制 yahoo 和 hotmail 使用的基于 SMTP 的标头/电子邮件并通过 Telnet 发送,但我收到的电子邮件不显示包含的附件​​,但它确实正确显示了消息。

我怀疑是什么原因造成的:

我认为我的电子邮件格式不正确,尽管在网上搜索了许多文章(以及试图掌握复杂且难以阅读的 RFC),但我没有找到任何有用或简洁的文章来解释如何使用所有SMTP 中的三个(纯文本、html 和附件)正确。我花了几天时间尝试更改代码,但我要么得到只是消息(无附件),要么得到整个 SMTP 数据正文显示(包括边界、html 代码等)。

我希望通过这个问题实现的目标:

我希望有人可以查看我在下面收集的信息,并能够告诉我我遗漏了什么(或者电子邮件的格式究竟有多不正确)。

调试信息:

我将发送到 SMTP 服务器的信息的副本提供给文件,并将信息粘贴到 pastebin(删除/编辑了任何个人信息 - Base64 编码附件只是另一封电子邮件的文本文件从 IMAP 获取):

信息逐字发送(减去控制字符)到 SMTP 服务器:

http://pastebin.com/QYwzWT0S

我在电子邮件客户端中看到的内容(注意没有附件):

http://i45.tinypic.com/29b1zci.jpg

我下载电子邮件时 IMAP 看到的内容(注意格式不正确):

http://pastebin.com/zv3PBr8N

正确格式的电子邮件在 IMAP 中应该是什么样子:

http://pastebin.com/3yBySbxU

我怀疑 SMTP 误解了我发送的内容,这就是 IMAP 尝试检索电子邮件时缺少 multipart/alternative 的原因。我到底做错了什么?服务器期望什么?

[感谢您的支持 - 我可以重新启用链接!]

【问题讨论】:

如果用户在它们前面加上 http://,这些链接仍然可以使用 - 我不得不禁用它们,因为新用户只能放置两个链接。 对此有任何可能的帮助吗? 【参考方案1】:

我清理了多部分边界说明符并得到了这个,它适用于我的服务器(我在这里省略了 SMTP 命令):

From: "Edited Out" <editedout@yahoo.com> 
To: "Edited Out" <editedout@yahoo.com> 
Subject: Testing 4
MIME-Version: 1.0
Content-Type: multipart/alternative;
  boundary="boundary-type-1234567892-alt"

--boundary-type-1234567892-alt
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable


Testing the text to see if it works!

--boundary-type-1234567892-alt
Content-Type: text/html; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable


<html>Does this actually work?</html>

--boundary-type-1234567892-alt
Content-Transfer-Encoding: base64
Content-Type: text/plain;name="Here2.txt"
Content-Disposition: attachment;filename="Here2.txt"

KiAxMyBGRVRDSCAoQk9EWVtURVhUXSB7NjU5fQ0KLS1fZjZiM2I1ZWUtMjA3YS00ZDdiLTg0NTgtNDY5YmVlNDkxOGRhXw0    KQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PSJpc28tODg1OS0xIg0KQ29udGVudC1UcmFuc2Zlci1FbmNvZG    luZzogcXVvdGVkLXByaW50YWJsZQ0KDQoNCkp1c3Qgc2VlaW5nIHdoYXQgdGhpcyBhY3R1
YWxseSBjb250YWlucyEgCQkgCSAgIAkJICA9DQoNCi0tX2Y2YjNiNWVlLTIwN2EtNGQ3Yi04NDU4LTQ2OWJlZTQ5MThkYV8    NCkNvbnRlbnQtVHlwZTogdGV4dC9odG1sOyBjaGFyc2V0PSJpc28tODg1OS0xIg0KQ29udGVudC1UcmFuc2Zlci1FbmNvZG    luZzogcXVvdGVkLXByaW50YWJsZQ0KDQo8aHRtbD4NCjxoZWFkPg0KPHN0eWxlPjwhLS0N
Ci5obW1lc3NhZ2UgUA0Kew0KbWFyZ2luOjBweD0zQg0KcGFkZGluZzowcHgNCn0NCmJvZHkuaG1tZXNzYWdlDQp7DQpmb25    0LXNpemU6IDEwcHQ9M0INCmZvbnQtZmFtaWx5OlRhaG9tYQ0KfQ0KLS0+PC9zdHlsZT48L2hlYWQ+DQo8Ym9keSBjbGFzcz    0zRCdobW1lc3NhZ2UnPjxkaXYgZGlyPTNEJ2x0cic+DQpKdXN0IHNlZWluZyB3aGF0IHRo
aXMgYWN0dWFsbHkgY29udGFpbnMhIAkJIAkgICAJCSAgPC9kaXY+PC9ib2R5Pg0KPC9odG1sPj0NCg0KLS1fZjZiM2I1ZWU    tMjA3YS00ZDdiLTg0NTgtNDY5YmVlNDkxOGRhXy0tDQopDQpmbHlubmNvbXB1dGVyIE9LIEZFVENIIGNvbXBsZXRlZA


--boundary-type-1234567890-alt--

多部分电子邮件中的边界说明符是不太可能出现在电子邮件正文/附件中的任意文本。当它在前面显示两个破折号时,表示新部分的开头(包括第一部分。当它在开头和结尾显示两个破折号时,表示邮件的结尾。

您的原始邮件在邮件中间(紧跟在&lt;html&gt;Does this actually work?&lt;/html&gt; 之后)有这个“结束边界”标记,并且有两个不同的边界标记(--boundary-type-1234567890--boundary-type-1234567892-alt)。这就解释了为什么附件被遗漏了。

【讨论】:

我修改了它以匹配您的设置,但附件仍然丢失。我使用的两种不同的界限是基于我从 hotmail 电子邮件中得到的(你可以在 'correctly formatted email' link 下看到它)。虽然我必须承认我从未尝试将电子邮件发送到不同的 SMTP 服务器,但万一 yahoo 只是在不告诉我的情况下删除了附件。 看来雅虎根本不显示附件。 Hotmail 没有这样的问题,您的 SMTP 服务器也没有。通过 yahoo 检查 IMAP 中的电子邮件,仍然缺少多部分边界(即使附件仍然存在)。 是的,multipart/alternative 和 multipart/mixed 之间是有区别的。替代方案应该是相同内容的不同表示形式(通常是同一电子邮件的 HTML 与纯文本版本)。混合应该是附件,我猜。然而,在实践中,许多电子邮件客户端/MTA 忽略了这一点,只是将这些部分视为混合。 (注意,我用于测试的 SMTP 服务器是 Exchange 2010 SP1)。【参考方案2】:

事实证明这个问题非常微妙。

Hotmail 通常 (this was the original email I based it on ) 使用术语“多部分/替代”来表示电子邮件的多个部分。我在电子邮件中使用了“multipart/alternative”。

事实证明,yahoo 不喜欢“multipart/alternative”,并且只会在使用“multipart/mixed”一词时正确显示纯文本、html 和附件(因为我注意到符合 yahoo 的电子邮件使用这个词代替替代方案),结合 ejdyksen 的建议(尽管这两个建议都不适用于雅虎的服务器)。

虽然从技术上讲,这是“正确”的答案,但我会选择 ejdyksen 的答案,因为他的努力表明这是一些服务器端的技术问题(他的 SMTP 服务器和 hotmail 都显示了附件,而雅虎没有) .礼貌地支持 ejdyksen 的回答,因为他做了大部分的跑腿工作。

【讨论】:

以上是关于SMTP 中带有纯文本、HTML 和附件的电子邮件的正确电子邮件格式?的主要内容,如果未能解决你的问题,请参考以下文章

Python SMTP邮件模块

自动化发送邮件之SMTP

SMTP发送邮件

邮件模块

使用Python,SMTP发邮件到qq邮箱(文本/超链接/图片/表格/附件表格)

带有多个附件 + html 的 SMTP 邮件 Mime