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

Flask上传文件直接作为邮件附件发送(无需暂存)问题求助

解决Flask上传文件直接作为邮件附件发送(无服务器暂存)的0KB问题

问题核心:你当前代码中,Flask的FileStorage对象在读取时可能因流指针位置不正确,导致file.read()返回空内容,最终生成0KB附件。以下是修正方案:

修正后的代码

import os
import smtplib
import ssl
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
from flask import request

def upload_and_send_email():
    files = request.files.getlist("file")
    
    # 定义邮件发送方、接收方
    email_sender = os.environ['EMAILSENDER']
    # 注意:修正环境变量拼写(原代码为EMAILPASWOORD)
    email_password = os.environ['EMAILPASSWORD']
    email_receiver = Emailreceiver  # 假设Emailreceiver为已定义变量

    # 设置邮件主题和正文
    subject = 'Mail test'
    body = """
    Check if it works
    """

    em = MIMEMultipart()
    em['From'] = email_sender
    em['To'] = email_receiver
    em['Subject'] = subject
    # 明确指定正文为纯文本类型
    em.attach(MIMEText(body, 'plain'))

    for file in files:
        # 跳过未选择文件的情况
        if not file or file.filename == '':
            continue
        
        part = MIMEBase('application', "octet-stream")
        # 关键:重置文件流指针到起始位置,确保读取完整内容
        file.seek(0)
        part.set_payload(file.read())
        encoders.encode_base64(part)
        # 用引号包裹文件名,避免特殊字符解析问题
        part.add_header(
            'Content-Disposition',
            f'attachment; filename="{file.filename}"'
        )
        em.attach(part)

    # 建立SSL连接并发送邮件
    context = ssl.create_default_context()
    with smtplib.SMTP_SSL('smtp.gmail.com', 465, context=context) as smtp:
        smtp.login(email_sender, email_password)
        smtp.sendmail(email_sender, email_receiver, em.as_string())

关键修正点

  • 重置文件流指针:调用file.read()前执行file.seek(0),确保从文件起始位置读取内容。部分场景下(如框架内部读取过文件头信息),流指针会停在文件末尾,导致后续读取返回空。
  • 过滤空文件:添加判断跳过未选择文件的情况,避免生成无效附件。
  • 文件名引号包裹:在Content-Disposition头中用双引号包裹文件名,避免文件名含空格或特殊字符时出现解析错误。
  • 修正环境变量拼写:原代码中EMAILPASWOORD为拼写错误,改为EMAILPASSWORD(若你的环境变量确实用错误拼写则忽略此点)。

原理说明

Flask的request.files返回的FileStorage是文件流对象,当流指针不在起始位置时,read()会返回空字节串。通过seek(0)重置指针到开头,即可完整读取上传文件内容,无需暂存到服务器磁盘,直接作为附件发送。

内容的提问来源于stack exchange,提问作者Skay

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 05:30:08