发送多附件邮件时附件名丢失变为ATT00001.xlsx求助
解决邮件附件文件名变为ATT00001.xlsx的问题
我看到你已经尝试添加邮件正文,但问题依然存在——核心问题出在你把附件的Content-Disposition头加到了整个MIMEMultipart邮件对象上,而不是每个单独的附件对象上。这会导致邮件客户端无法正确识别每个附件的文件名,从而用默认的ATT00001这类名称替代。
错误代码的问题点
在你的循环里,这行代码是错误的:
msg.add_header('Content-Disposition', 'attachment', filename=file_name)
你把附件的 disposition 头加到了整个邮件(msg)上,而不是当前处理的attachment对象。每个附件都需要自己独立的Content-Disposition头来声明文件名。
修正后的完整代码
把设置头的代码移到每个附件对象上,同时优化一些细节(比如文件名的获取、content_type的处理):
import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.base import MIMEBase from email import encoders from email.utils import encode_rfc2231 msg = MIMEMultipart() msg['Subject'] = subject msg['To'] = 'abc@sample.com' msg['From'] = sender # 添加邮件正文 body_part = MIMEText(body, 'plain') msg.attach(body_part) for file_path in file_paths: # 更简洁的文件名获取方式 file_name = file_path.split('/')[-1] # 打开附件文件 fp = open(file_path, 'rb') # 这里建议根据每个文件的实际类型设置maintype和subtype,而不是统一用一个ctype # 如果不确定类型,可以用application/octet-stream作为通用类型 attachment = MIMEBase('application', 'octet-stream') attachment.set_payload(fp.read()) fp.close() # 编码附件内容 encoders.encode_base64(attachment) # 给当前附件设置Content-Disposition头,处理特殊字符(比如中文) attachment.add_header( 'Content-Disposition', 'attachment', filename=encode_rfc2231(file_name, charset='utf-8') ) # 将附件添加到邮件对象 msg.attach(attachment) # 发送邮件 smtp_client = smtplib.SMTP(f"{smtp_host}:{smtp_port}") smtp_client.starttls() smtp_client.login(sender, smtp_login_password) smtp_client.sendmail(sender, 'abc@sample.com', msg.as_string()) smtp_client.quit()
额外注意事项
- 文件名编码:如果文件名包含中文或特殊字符,使用
encode_rfc2231可以确保邮件客户端正确解析文件名,避免乱码或无法识别的问题。 - Content-Type匹配:如果你的附件是特定类型(比如xlsx、pdf),最好根据文件扩展名获取对应的content_type,而不是用通用的
application/octet-stream。可以用mimetypes模块自动获取:import mimetypes ctype, encoding = mimetypes.guess_type(file_path) if ctype is None or encoding is not None: ctype = 'application/octet-stream' maintype, subtype = ctype.split('/', 1) attachment = MIMEBase(maintype, subtype) - 避免重复设置头:不要在MIMEMultipart对象上设置附件相关的头,所有附件的属性都应该绑定到各自的MIMEBase对象上。
内容的提问来源于stack exchange,提问作者abhijit nag
相关产品推荐
相关产品推荐

