233星空xt 2025-06-26 23:13 采纳率: 100%
浏览 20
已结题

使用fastapi_mail发送邮箱时遇到错误

使用fastapi_mail发送邮箱时,邮箱收到了,但是程序却报错了

这是代码部分

from fastapi_mail import FastMail, MessageSchema, ConnectionConfig, MessageType
from app.core.setting import settings
from typing import List

from pydantic import EmailStr

_conf = ConnectionConfig(
    MAIL_USERNAME=settings.mail_username,
    MAIL_PASSWORD=settings.mail_password,
    MAIL_FROM=settings.mail_from,
    MAIL_PORT=settings.mail_port,
    MAIL_SERVER=settings.mail_server,
    MAIL_STARTTLS=settings.mail_starttls,
    MAIL_SSL_TLS=settings.mail_ssl,
)


async def send_email(subject: str, recipients: List[EmailStr], body: str, subtype: MessageType = MessageType.plain):
    message = MessageSchema(
        subject=subject,
        recipients=recipients,
        body=body,
        subtype=subtype
    )
    fm = FastMail(_conf)
    await fm.send_message(message)

报错如下

  File "D:\WebProjects\留言板\后端\app\api\v1\endpoints\verify.py", line 25, in verify_email
    await send_email(subject="验证码", recipients=[request.email], body=f"你的验证码是:{verification_code}")
  File "D:\WebProjects\留言板\后端\app\services\email.py", line 28, in send_email
    await fm.send_message(message)
  File "D:\WebProjects\留言板\后端\venv\Lib\site-packages\fastapi_mail\fastmail.py", line 151, in send_message
    async with Connection(self.config) as session:
  File "D:\WebProjects\留言板\后端\venv\Lib\site-packages\fastapi_mail\connection.py", line 31, in __aexit__
    await self.session.quit()
  File "D:\WebProjects\留言板\后端\venv\Lib\site-packages\aiosmtplib\smtp.py", line 780, in quit
    response = await self.execute_command(b"QUIT", timeout=timeout)
  File "D:\WebProjects\留言板\后端\venv\Lib\site-packages\aiosmtplib\smtp.py", line 548, in execute_command
    response = await self.protocol.execute_command(
  File "D:\WebProjects\留言板\后端\venv\Lib\site-packages\aiosmtplib\protocol.py", line 291, in execute_command
    response = await self.read_response(timeout=timeout)
  File "D:\WebProjects\留言板\后端\venv\Lib\site-packages\aiosmtplib\protocol.py", line 252, in read_response
    result = await asyncio.wait_for(self._response_waiter, timeout)
  File "D:\Python310\lib\asyncio\tasks.py", line 447, in wait_for
    return fut.result()
  File "D:\WebProjects\留言板\后端\venv\Lib\site-packages\aiosmtplib\protocol.py", line 162, in data_received
    response = self._read_response_from_buffer()
  File "D:\WebProjects\留言板\后端\venv\Lib\site-packages\aiosmtplib\protocol.py", line 214, in _read_response_from_buffer
    raise SMTPResponseException(
aiosmtplib.errors.SMTPResponseException: (-1, "Malformed SMTP response line: b'\\x00\\x00\\x00\\x1a\\x00\\x00\\x00\\n'")

我直接用aiosmtplib是没问题的

import asyncio
from email.mime.text import MIMEText
from email.header import Header
from app.core.setting import settings

# 收件人和邮件内容
mail_to = "xkgt@qq.com"
subject = "测试邮件 - 来自 Python 脚本(异步)"
body = "这是一个使用 aiosmtplib 发送的测试邮件正文。"

# 创建邮件对象
msg = MIMEText(body, 'plain', 'utf-8')
msg['From'] = settings.mail_from
msg['To'] = mail_to
msg['Subject'] = Header(subject, 'utf-8')

# 异步发送邮件
async def send_email_async():
    try:
        from aiosmtplib import SMTP

        smtp = SMTP(
            hostname=settings.mail_server,
            port=settings.mail_port,
            username=settings.mail_username,
            password=settings.mail_password,
            use_tls=settings.mail_ssl,
            start_tls=settings.mail_starttls,
        )

        async with smtp:
            await smtp.send_message(msg, sender=settings.mail_from, recipients=[mail_to])
            print(" 邮件发送成功(异步)!")

    except Exception as e:
        print(" 邮件发送失败(异步):", str(e))

# 运行异步任务
if __name__ == "__main__":
    asyncio.run(send_email_async())

发送成功

但是换fastapi_mail就出错了

import asyncio
from fastapi_mail import FastMail, MessageSchema, ConnectionConfig
from pydantic import EmailStr
from app.core.setting import settings

# 配置邮件连接
conf = ConnectionConfig(
    MAIL_USERNAME=settings.mail_username,
    MAIL_PASSWORD=settings.mail_password,
    MAIL_FROM=settings.mail_from,
    MAIL_PORT=settings.mail_port,
    MAIL_SERVER=settings.mail_server,
    MAIL_STARTTLS=settings.mail_starttls,
    MAIL_SSL_TLS=settings.mail_ssl,  # 如果使用 SSL/TLS
)

async def send_email_async():
    message = MessageSchema(
        subject="测试邮件",
        recipients=["xkgt@qq.com"],  # 收件人列表
        body="这是一个使用 FastAPI-Mail 发送的测试邮件正文。",
        subtype="plain"
    )

    fm = FastMail(conf)
    try:
        await fm.send_message(message)
        print(" 邮件发送成功(FastAPI-Mail)!")
    except Exception as e:
        print(" 邮件发送失败(FastAPI-Mail):", str(e))

if __name__ == "__main__":
    asyncio.run(send_email_async())
 邮件发送失败(FastAPI-Mail): (-1, "Malformed SMTP response line: b'\\x00\\x00\\x00\\x1a\\x00\\x00\\x00\\n'")
  • 写回答

5条回答 默认 最新

  • 一杯年华@编程空间 2025-06-26 23:18
    关注

    一杯年华@编程空间帮您解答,本答案结合 ChatGPT4.0和DeepSeek整理

    我曾经遇到过类似的问题,在使用fastapi_mail发送邮件时,明明邮件已经成功送达,但程序却抛出了错误,这确实让人很困惑。经过分析,我认为可能是以下原因导致的。

    从你描述的情况来看,核心问题在于fastapi_mail与邮件服务器的交互过程中出现了响应解析错误。虽然aiosmtplib能正常工作,但fastapi_mail作为封装库,可能在配置处理或连接管理上有特殊要求。以下是几种可能的解决方案:

    解决方案

    • 检查配置参数的兼容性:重点关注MAIL_STARTTLS和MAIL_SSL_TLS这两个参数。这两个参数分别控制是否启用STARTTLS加密和SSL/TLS加密,若同时启用或配置与服务器要求不匹配,就可能导致连接时的协议冲突。比如,若服务器要求使用SSL/TLS,就应将MAIL_SSL_TLS设为True,同时确保MAIL_STARTTLS为False;若使用STARTTLS,就需确认端口是否对应(如587端口常搭配STARTTLS),并关闭SSL/TLS选项。
    • 排查依赖版本冲突:fastapi_mail依赖aiosmtplib,若两者版本不兼容,可能会在解析服务器响应时出现异常。你可以尝试更新fastapi_mail到最新版本,或者查看项目依赖中aiosmtplib的版本是否与fastapi_mail兼容。例如,某些旧版本的aiosmtplib可能在处理特定响应格式时存在缺陷,升级后或许能解决问题。
    • 关注连接关闭时的异常处理:错误提示出现在会话退出(quit)阶段,可能是服务器在关闭连接时返回的响应格式不符合fastapi_mail的预期。你可以尝试在发送邮件后手动处理连接关闭,或者检查fastapi_mail的连接管理逻辑是否存在漏洞,比如是否正确处理了服务器返回的非标准响应。

    最优方案讲解

    在这些解决方案中,优先检查配置参数的兼容性是最优选择。因为你使用aiosmtplib直接发送邮件是正常的,这说明服务器配置本身没有问题,问题很可能出在fastapi_mail的配置参数与服务器要求不匹配上。

    具体来说,你可以先确认邮件服务器所使用的加密方式。如果是Gmail等常用邮箱,通常使用SSL/TLS加密,对应的端口是465,此时应将MAIL_SSL_TLS设为True,MAIL_STARTTLS设为False;若服务器使用STARTTLS加密,端口一般为587,这时则要将MAIL_STARTTLS设为True,MAIL_SSL_TLS设为False。同时,还要确保MAIL_PORT的设置与加密方式对应,避免因端口错误导致协议握手失败。

    通过仔细核对这些配置参数,很多因协议不兼容导致的错误都能得到解决。这一方案直接针对问题根源,操作起来也比较简单,不需要修改大量代码,能够快速定位和解决问题。

    希望这些建议能帮你解决问题。如果还有其他疑问,请继续留言。若觉得有用,请楼主采纳。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

问题事件

  • 系统已结题 7月4日
  • 已采纳回答 6月26日
  • 创建了问题 6月26日