Flask用MultipleFileField批量发多附件邮件仅首个收件人附件正常
问题原因
request.files中拿到的文件对象是流式对象,调用read()方法读取完内容后,文件指针会移动到文件末尾,后续再次调用read()只能获取到空字节。你的代码中每遍历一个收件人就会重新读取一次附件文件流,只有第一个收件人能拿到完整的附件二进制数据,后续收件人的附件都是空内容,所以显示为损坏文件。
修复方案
最优方案是提前将所有附件的内容读取缓存,遍历收件人时直接复用缓存的附件数据,避免重复读取文件流:
# 提前缓存所有附件数据,仅读取一次文件流 attachment_cache = [] for f in request.files.getlist('attachment'): attachment_cache.append({ "filename": f.filename, "content_type": f.content_type, "data": f.read() }) with mail.connect() as conn: for contact in contacts: message = "Hi %s \n\n" % (contact['name']).capitalize() message += body msg = Message(recipients=(contact['email']).split(), sender=sender, html=message, subject=subject, ) # 直接使用缓存的附件数据添加到邮件 for att in attachment_cache: msg.attach(**att) conn.send(msg) return Response("Success")
如果不想提前占用内存缓存附件,也可以在每次读取文件前重置文件指针位置,不过该方案会重复读取文件,效率更低:
with mail.connect() as conn: for contact in contacts: message = "Hi %s \n\n" % (contact['name']).capitalize() message += body msg = Message(recipients=(contact['email']).split(), sender=sender, html=message, subject=subject, ) for f in request.files.getlist('attachment'): f.seek(0) # 重置文件指针到文件开头 msg.attach(filename=f.filename, content_type=f.content_type, data=f.read()) conn.send(msg) return Response("Success")
内容的提问来源于stack exchange,提问作者AbrarWali
相关产品推荐
相关产品推荐

