
本文详解如何在 flask 项目中正确集成 smtp 邮件发送功能,解决表单数据接收后未触发邮件发送的常见问题,并提供可直接运行的完整示例。
本文详解如何在 flask 项目中正确集成 smtp 邮件发送功能,解决表单数据接收后未触发邮件发送的常见问题,并提供可直接运行的完整示例。
在 Flask 中实现“联系表单 → 邮件通知”功能时,一个典型误区是:仅定义了 send_email() 函数,却未在路由处理逻辑中显式调用它。从日志可见,POST /contact 请求已成功接收表单数据(如 Sara、[email protected] 等),但邮件未发出——这说明后端未执行发送逻辑,而非 SMTP 配置或网络问题。
✅ 正确实现步骤
1. 完善 Flask 路由逻辑(关键修复)
确保在 @app.route('/contact', methods=['POST']) 视图函数中解析表单并调用 send_email():
from flask import Flask, request, render_template, flash
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
app = Flask(__name__)
app.secret_key = 'your-secret-key' # 用于 flash 消息
@app.route('/contact', methods=['GET', 'POST'])
def contact():
if request.method == 'POST':
# 获取表单数据
name = request.form.get('name', '').strip()
email = request.form.get('email', '').strip()
phone = request.form.get('phone', '').strip()
message = request.form.get('message', '').strip()
# 基础验证(生产环境建议增强)
if not all([name, email, message]):
flash('请填写必填字段(姓名、邮箱、留言)', 'error')
return render_template('contact.html', msg_sent=False)
try:
send_email(name, email, phone, message)
flash('消息已成功发送!感谢您的联系。', 'success')
return render_template('contact.html', msg_sent=True)
except Exception as e:
flash(f'发送失败:{str(e)}', 'error')
return render_template('contact.html', msg_sent=False)
return render_template('contact.html', msg_sent=False)2. 优化邮件发送函数(提升健壮性)
原代码使用纯字符串构造邮件易出错,推荐改用 MIMEText 构建标准邮件体,并添加异常捕获与日志:
def send_email(name, email, phone, message):
smtp_server = 'smtp.gmail.com'
smtp_port = 587
smtp_username = 'your_gmail@gmail.com' # 替换为你的 Gmail 地址
smtp_password = 'your_app_password' # 替换为 Google App Password(非账户密码)
from_email = smtp_username
to_email = 'recipient@example.com' # 接收方邮箱
subject = f'新联系表单提交 - {name}'
# 构建 MIME 邮件
msg = MIMEMultipart()
msg['From'] = from_email
msg['To'] = to_email
msg['Subject'] = subject
msg.attach(MIMEText(
f"姓名: {name}\n邮箱: {email}\n电话: {phone}\n\n留言:\n{message}",
'plain', 'utf-8'
))
try:
with smtplib.SMTP(smtp_server, smtp_port) as server:
server.starttls() # 启用 TLS 加密
server.login(smtp_username, smtp_password)
server.send_message(msg)
print(f"✅ 邮件已发送至 {to_email}")
except Exception as e:
print(f"❌ 邮件发送失败: {e}")
raise3. 前端注意事项
- 确保表单 action="{{ url_for('contact') }}" 指向正确的 Flask 端点;
- 使用 flash() 在模板中显示成功/错误提示(已在 contact.html 中通过 {% if msg_sent %} 处理);
- 禁用前端 JS 表单拦截:检查是否引入了第三方表单脚本(如 sb-forms-latest.js)导致 POST 被拦截——若无需其功能,建议移除。
⚠️ 安全与配置提醒
- Gmail App Password:必须在 Google 账户 → 安全 → 两步验证 → App 密码 中生成,不可使用账户登录密码;
-
环境变量保护:切勿将 smtp_username 和 smtp_password 硬编码在代码中,应使用 os.getenv() 读取:
import os smtp_username = os.getenv('SMTP_USERNAME') smtp_password = os.getenv('SMTP_PASSWORD') - 错误处理:生产环境务必捕获 smtplib.SMTPAuthenticationError、smtplib.SMTPRecipientsRefused 等具体异常,便于快速定位问题。
通过以上调整,表单提交后将自动触发邮件发送,并返回清晰的成功/失败反馈。核心要点始终是:接收数据 ≠ 发送邮件,必须显式调用发送函数并妥善处理结果。
立即学习“前端免费学习笔记(深入)”;



















