Django Web应用通过Gmail SMTP发信失败报TimeoutError如何解决
Django 调用Gmail SMTP发信报10060连接超时解决方案
先修正配置里的显性错误
现有配置有两个直接会导致异常的硬伤:
- 配置项拼写错误:SMTP端口参数名写成了
EMAIL_POSRT,Django无法识别该配置,会默认使用25端口发信,而25端口几乎被所有本地运营商、网络环境封禁,必然触发连接超时 - 发信密码为空:
EMAIL_HOST_PASSWORD留空,即使网络连通也会因为鉴权失败被服务端拒绝,且Gmail已不支持直接使用账号登录密码做SMTP鉴权
修正后的标准配置如下:
# SMTP Configuration EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.gmail.com' EMAIL_PORT = 587 # 修正之前的拼写错误,注意是PORT不是POSRT EMAIL_USE_TLS = True EMAIL_HOST_USER = 'fhcollege@gmail.com' EMAIL_HOST_PASSWORD = '你的Gmail应用专用密码' # 不要填账号登录密码,不要留空 EMAIL_TIMEOUT = 10 # 配置显式超时时间,避免无意义等待
说明:Gmail应用专用密码需要在账号开启两步验证后,在谷歌账号安全设置页生成,是16位的随机字符串,生成后直接复制填入配置即可。
按优先级排查网络连通性
WinError 10060是TCP层连接建立失败的典型报错,和业务代码逻辑无关,按以下顺序排查:
- 本地网络连通性校验
打开命令提示符执行端口检测:tcping smtp.gmail.com 587- 如果返回连接超时,先确认当前网络环境可以正常访问谷歌服务,国内直连Gmail SMTP默认是不通的;同时检查本地防火墙、杀毒软件是否拦截了Python进程的外发请求,公司/校园网环境需要确认网管没有封禁SMTP外发端口。
- 如果tcping连通,再执行
telnet smtp.gmail.com 587,能看到SMTP服务返回的欢迎信息才算网络层完全正常。
- 部署环境额外校验
如果是云服务器部署,需要检查云服务商安全组是否放开587端口的外发权限,部分云厂商默认封禁SMTP端口防止垃圾邮件滥发,需要提交工单申请解封。
发信逻辑验证
现有views里的发信代码没有语法问题,不要直接走页面请求调试,先在Django shell里做最小化验证,排除其他业务逻辑干扰:
- 项目目录下执行命令打开交互shell:
python manage.py shell - 执行测试发信代码:
from django.core.mail import EmailMessage from django.conf import settings email = EmailMessage( 'PAYMENT SUCCESSFULL', 'welcome', settings.EMAIL_HOST_USER, ['fhcollege@google.com'] ) email.fail_silently = False email.send()
代码执行后返回值为1即代表发信成功,此时再回到页面触发业务逻辑即可正常发信。
补充踩坑说明
- 不要尝试使用Gmail的“低安全性应用访问”功能,该入口2022年已被谷歌全量下线,所有SMTP调用必须使用两步验证生成的应用专用密码
- 如果暂时无法解决Gmail连通性问题,可以先换用其他邮箱服务商的SMTP服务做测试,确认Django发信逻辑本身正常后,再回头排查Gmail的网络和配置问题
内容的提问来源于stack exchange,提问作者Akhil Varghese
相关产品推荐
相关产品推荐

