使用Django发送邮件遇阻:生产环境出现upstream prematurely错误求助
解决Django通过Gmail发送邮件的「upstream prematurely closed」错误
嘿,这个问题我之前踩过坑,核心原因其实是Google早在2022年就彻底停用了「不太安全的应用」访问权限,你之前的配置自然没法正常工作,咱们一步步来修复:
第一步:启用2步验证并生成「应用专用密码」
现在Gmail仅允许通过「应用专用密码」来授权第三方应用发送邮件,而生成这个密码的前提是你的账号必须开启2步验证:
- 登录你的Google账号,进入「安全」设置页面
- 找到「2步验证」并完成开启(如果还没开的话)
- 开启后,在同一页面找到「应用专用密码」选项
- 生成一个新的应用专用密码(随便给个名称,比如「Django邮件服务」)
- 把生成的16位无空格密码,替换到settings.py里的
EMAIL_HOST_PASSWORD字段
第二步:修正Django邮件配置
确保你的settings.py配置参数正确,这里给你两种经过验证的可用方案:
方案1:使用TLS协议(端口587)
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.gmail.com' EMAIL_PORT = 587 EMAIL_HOST_USER = 'mymail@gmail.com' EMAIL_HOST_PASSWORD = '你的应用专用密码' # 替换成新生成的密码 EMAIL_USE_TLS = True DEFAULT_FROM_EMAIL = 'mymail@gmail.com'
方案2:使用SSL协议(端口465)
如果TLS连接遇到网络限制,可以切换到SSL:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.gmail.com' EMAIL_PORT = 465 EMAIL_HOST_USER = 'mymail@gmail.com' EMAIL_HOST_PASSWORD = '你的应用专用密码' EMAIL_USE_SSL = True # 注意这里是USE_SSL,而非USE_TLS DEFAULT_FROM_EMAIL = 'mymail@gmail.com'
第三步:排查生产服务器的网络限制
如果替换密码后仍报错,大概率是服务器的网络规则限制了邮件端口:
- 先测试端口连通性:在服务器终端执行
telnet smtp.gmail.com 587,如果连接失败,说明端口被封禁,需要联系服务器提供商解封 - 部分云服务商(如阿里云、腾讯云)默认会屏蔽587/465端口,需要在控制台手动开启邮件服务权限
- 可以用原生Python代码测试邮件发送,排除Django框架的问题:
import smtplib from email.mime.text import MIMEText msg = MIMEText('这是一封测试邮件') msg['Subject'] = 'Django邮件测试' msg['From'] = 'mymail@gmail.com' msg['To'] = '收件人邮箱@xxx.com' try: with smtplib.SMTP('smtp.gmail.com', 587) as server: server.starttls() server.login('mymail@gmail.com', '你的应用专用密码') server.send_message(msg) print('邮件发送成功!') except Exception as e: print(f'发送失败:{str(e)}')
额外注意事项
- 确保
DEFAULT_FROM_EMAIL和EMAIL_HOST_USER完全一致,否则可能被Gmail的反垃圾机制拦截 - 如果还是有问题,可以查看Gmail的「最近活动」记录,确认是否有异常登录被拦截的情况
内容的提问来源于stack exchange,提问作者user9751373
相关产品推荐
相关产品推荐

