Python MIMEMultipart邮件非TXT附件损坏无法打开问题求助
问题原因及修复方案
核心问题
非文本附件损坏的根源是二进制数据未做Base64编码就直接作为邮件payload,同时创建MIME对象时参数错误,导致原始二进制内容被错误解析为文本格式,最终附件内容损坏。
具体修复点
- 修正MIME对象初始化参数:创建
MIMEImage/MIMEAudio时,不应传字符串'r',而是直接传入文件的二进制内容。 - 对非文本附件做Base64编码:所有二进制类型的附件(图片、音频、二进制文件)需要进行Base64编码,避免二进制数据被错误处理。
- 规范MIMEBase类型附件的编码:使用
MIMEBase时,需通过内置编码工具处理payload,并自动设置对应的传输编码头。
修复后的load_attachments函数
from email import encoders from email.mime.base import MIMEBase from email.mime.text import MIMEText from email.mime.image import MIMEImage from email.mime.audio import MIMEAudio import mimetypes def load_attachments(mail, files): for file in files: # file is a FieldStorage content_type, encoding = mimetypes.guess_type(file.filename) if content_type is None or encoding is not None: content_type = 'application/octet-stream' main_type, sub_type = content_type.split('/', 1) file_content = file.value # 获取FieldStorage的二进制内容 if main_type == 'text': # 文本文件指定字符集,避免乱码 attachment = MIMEText(file_content, _subtype=sub_type, _charset='utf-8') elif main_type == 'image': # 图片直接传入二进制内容 attachment = MIMEImage(file_content, _subtype=sub_type) elif main_type == 'audio': # 音频直接传入二进制内容 attachment = MIMEAudio(file_content, _subtype=sub_type) else: # 其他二进制文件用MIMEBase做Base64编码 attachment = MIMEBase(main_type, sub_type) attachment.set_payload(file_content) encoders.encode_base64(attachment) # 自动完成编码并设置头信息 filename = file.filename attachment.add_header('Content-Disposition', 'attachment', filename=filename) mail.attach(attachment) return mail
额外说明
- 文本文件指定
utf-8字符集,可避免不同系统下的编码乱码问题。 encoders.encode_base64会自动处理二进制内容的编码,并设置Content-Transfer-Encoding头,无需手动添加。- 原代码中
MIMEText('r', ...)的写法错误,'r'被当作了文本内容,修复后改为直接传入文件的真实内容,避免TXT附件出现异常。
内容的提问来源于stack exchange,提问作者stark_1
相关产品推荐
相关产品推荐

