我有一个UTF-8编码的XML文件,它以附件的形式通过电子邮件发送。当电子邮件收件人打开电子邮件并保存附件时,XML文件不再是UTF-8(而是报告ANSI编码)。在这种情况下,收件人使用Microsoft Outlook,如果重要的话。
我在一个不能依赖合适的MIME库可用性的环境中编程,所以我需要了解我的错误。
在通过电子邮件发送XML文件之前,在服务器上创建它之后,我可以看到使用Linux文件命令它是一个UTF-8文件。与此分开,XML也有一个版本标题<?xml version="1.0" encoding="UTF-8"?>
(这与我的问题并不相关,但为了完整性,我将其包括在内)。我很确定我的代码通过电子邮件发送文件是问题所在,但我不确定是否采用了“正确”的方式。
我发送的标题是:
"Mime-Version" "1.0"
"Content-Type" "multipart/mixed; boundary="__==NAHDHDH2.28ABSDJxjhkjhsdkjhd___"\n\n"
电子邮件的正文是:
--__==NAHDHDH2.28ABSDJxjhkjhsdkjhd___\n
Content-Type: text/plain; charset="utf-8"; format=flowed\n
Content-Transfer-Encoding: 7bit\n\n
Please find attached the data file generated
--__==NAHDHDH2.28ABSDJxjhkjhsdkjhd___\n
Content-Type: text/plain; charset="utf-8"\n
Content-Disposition: attachment; filename="My_File_Name"\n\n
XML FILE CONTENTS GO HERE
--__==NAHDHDH2.28ABSDJxjhkjhsdkjhd___--\n
问题:
quoted-printable
,8bit
还是其他类型的
Content-Transfer-Encoding
在这里?我尝试了所有这些,但它
没有改变结果。 Content-Type: text/plain
对于XML附件是否正确? 答案 0 :(得分:4)
通过指定text/plain
,你基本上放弃了对远程客户端文本处理能力的控制,这在这种特殊情况下显然是有限的。 XML是按规范的Unicode,因此通过选择更好的内容类型,您更有可能成功。请尝试使用text/xml
或application/xml
,甚至是完全不透明的application/octet-stream
,它应仅允许收件人以字节为单位的相同内容将其保存在磁盘上形式。
内容传输编码根本不应影响此行为,但由于您似乎不清楚其重要性,因此这里有一个简短的讨论。
内容转移编码完全透明;它不会影响交付的内容或远程客户端可以使用它做什么。选择哪种内容传输编码取决于数据的性质以及需要传输的电子邮件系统的功能。如果它不是8位清理,则需要一个7位CTE来封装它。如果内容的行太长而无法容纳到SMTP中,则需要将其封装为具有较短行的内容。但远程客户端将提取另一端封装内的任何内容。使用任何情况决定。
针对不同情况,存在内容传输编码的层次结构:
7bit
是合适的。然后它甚至可以在没有修改的情况下存活旧的SMTP传输。在没有任何明确的Content-Transfer-Encoding:
标头的情况下,根据标准,这是默认值(尽管您经常会看到包含8位数据的内容,而没有明确的CTE,甚至是明确的7bit
声明)。
8bit
放宽了对数据进行7位清理的要求。如果传输此消息的所有系统都支持ESMTP 8BITMIME
扩展名,则对于行长度受限的数据,这应该没问题。
binary
还允许无限制的行长度。理论上,您应该能够使用它来传递不受限制的内容,但在实践中,这似乎会在系统严格遵守规范时触发故障。典型的症状是超长线路在传输过程中被截断或折叠,违反了有效载荷的完整性。为了避免这样的问题(并且为了更好地遵守互操作性标准的文字和精神),您最好使用以下方法之一。
base64
接受不受限制的内容,但会以满足严格限制行长度和严格约束的7位字符集的严格要求的格式对其进行编码。它将有效负载扩展到原始大小的4/3以上。例如:
ugqcA7R5cPq667vNaSifRUH9HsW00NqZ1gwICk0pNrUkXFpNIFOpbf3o
5ml8cqqSygkp8KBgPbHrqnDXvZTEBOkNo7ThE+BAvexa75Tm0Ebo/Yjl
y697pMp1+dnSlk3YTqxkPI9vqpple13dXLHlvnFDmSi0gqIMSwo7kUFD
SivAWhyCBR6tFO3lY1Pk6lz78+zgL28VthI72kVRkrWWtzoFef/4u5Ip
GR00CtsNNEJo01GAQGpkTNFT9U9Q/UI9CMGgaI9E9RkMaTDTQICBEyaE
woSCQOrNGA==
quoted-printable
同样接受任意内容,但将选定的字节编码为原始字节的3倍。当大多数输入是ASCII时,这是可容忍的开销量。换句话说,这适用于偶尔使用非ASCII内容的粗略文本格式,例如使用8位编码的许多西方语言中的文本,或者像HTML这样的格式,其中ASCII标记优于实际内容,几乎任何语言。例如: <?xml version=3D"1.0" encoding=3D"UTF-8"?>h=C3=ABll=C3=B6 =
w=C3=B6rld
引用可打印并不难实现,并且似乎适合您的场景。
所有这些都在MIME RFC 2045到2048年编纂。维基百科有很好的可读文章,例如base64和quoted-printable。
从您的描述中不清楚您是否只是声明您的内容可以引用,或实际编码。我已经看到人们做了前者,并且当它没有工作时表现得很惊讶,但希望你能做到后者。只是一个警示故事。