You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 01:57:07