如何在 Flask 中正确处理表单提交并发送邮件
技术百科
碧海醫心
发布时间:2026-01-01
浏览: 次 本文详解 flask 应用中接收 html 表单数据并通过 smtp(gmail)自动发送邮件的完整实现,重点解决“表单数据已接收但邮件未发出”的常见问题。
在 Flask 中实现联系表单(Contact Form)的邮件发送功能,关键在于前后端逻辑的完整串联:HTML 表单需正确提交至 Flask 路由,该路由必须显式调用邮件发送函数,并妥善处理请求方法、数据提取与异常反馈。从你提供的日志可见,POST /contact 请求已成功到达服务器("POST /contact HTTP/1.1" 200 -),且控制台也打印出了表单字段值(如 Sara、[email protected] 等),这说明数据接收无误——但邮件未发出,根本原因正是:send_email() 函数未被实际调用。
✅ 正确的 Flask 路由实现(main.py)
你需要确保 /contact 路由同时支持 GET(渲染页面)和 POST(处理提交),并在 POST 分支中解析表单并调用 send_email():
from flask import Flask, render_template, request, flash
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
app = Flask(__name__)
app.secret_key = 'your-secret-key-here' # 用于 flash 消息
def send_email(name, email, phone, message):
smtp_server = 'smtp.gmail.com'
smtp_port = 587
smtp_username = 'your-verified-gmail@gmail.com' # 替换为你的 Gmail 地址
smtp_password = 'your-app-password' # 替换为 Google App Password(非邮箱密码!)
from_email = smtp_username
to_email = 'recipient@example.com' # 接收邮件的目标地址
subject = f'New Contact Form Submission from {name}'
# 使用标准 MIME 格式构造邮件(更可靠,避免纯字符串格式问题)
msg = MIMEMultipart()
msg['From'] = from_email
msg['To'] = to_email
msg['Subject'] = subject
msg.attach(MIMEText(f"""\
Name: {name}
Email: {email}
Phone: {phone}
Message: {message}
""", 'plain'))
try:
with smtplib.SMTP(smtp_server, smtp_port) as server:
server.starttls() # 启用 TLS 加密
server.login(smtp_username, smtp_password)
server.send_message(msg)
return True
except Exception as e:
print(f"Email sending failed: {e}")
return False
@app.route('/contact', methods=['GET', 'POST'])
def contact():
if request.method == 'POST':
# ✅ 关键:从 request.form 提取数据
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('Please fill in all required fields.', 'error')
return render_template('contact.html', msg_sent=False)
# ✅ 关键:显式调用 send_email 并检查结果
if send_email(name, email, phone, message):
flash('Your message has been sent successfully!', 'success')
return render_template('contact.html', msg_sent=True)
else:
flash('Failed to send email. Please try again later.', 'error')
return render_template('contact.html', msg_sent=False)
# GET 请求:渲染空表单
return render_template('contact.html', msg_sent=False)? 重要注意事项
- Gmail App Password 必须启用两步验证后生成:直接使用邮箱密码会失败(Google 已禁用“不安全应用访问”)。前往 Google Account → Security → App passwords 生成 16 位密码。
- 不要硬编码敏感信息:生产环境应使用环境变量(如 os.getenv('SMTP_PASSWORD'))管理账号密码。
- 使用 MIMEText/MIMEMultipart 构造邮件:比拼接原始字符串更规范,兼容性更好,避免因换行、编码等问题导致邮件发送失败或内容乱码。
- 添加错误处理与用户反馈:try/except 捕获 SMTP 异常,并通过 flash() 向用户提示成功或失败状态(需在模板中渲染 get_flashed_messages())。
-
确保 contact.html 正确显示提示:在模板 中适当位置添加:
{% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} {% for category, message in messages %} {{ message }} {% endfor %} {% endif %} {% endwith %}
✅ 总结
表单数据“能打印却发不出邮件”,90% 的原因是:Flask 路由收到了 POST 请求,但忘记在代码中执行 send_email(...) 这一行。务必检查你的 /contact 视图函数是否包含对邮件函数的显式调用,并确保其位于 request.method == 'POST' 分支内。配合 MIME 邮件构造、App Password 配置和基础错误处理,即可稳定实现联系表单的邮件通知功能。
# ai
# 后端
# 可选
# 出了
# 表单
# google
# 常见问题
# 并在
# 关键在于
# 不出
# 不安全
# app
# 收到了
# word
# http
# go
# 路由
# 环境变量
# 并发
# html
# 编码
# 字符串
# red
# try
# protected
# 邮箱
# 表单提交
# 两步
# flask
# 邮件发送
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Win11怎么打开旧版计算器_Win11恢复传统计
- 如何使用Golang构建基础消息队列模拟_Gola
- Win11怎么关闭搜索历史 Win11清除搜索框最
- Win11怎么设置夜间模式_Windows11显示
- C#如何序列化对象为XML XmlSerializ
- c# 如何用c#实现一个支持优先级的任务队列
- Win10如何卸载Skype_Win10卸载Sky
- Win10怎样安装PPT模板_Win10安装PPT
- c++怎么实现高并发下的无锁队列_c++ std:
- Win11怎么设置默认输入法 Win11固定中文输
- PHP cURL GET请求:正确设置请求头与身份
- 如何在Golang中引入测试模块_Golang测试
- 如何使用Golang实现路由分组管理_Golang
- 如何在Golang中定义接口_抽象方法和多态实现
- 如何使用Golang实现路由参数绑定_使用Mux和
- Win11如何设置文件关联 Win11修改特定文件
- Win11如何关闭小娜Cortana Win11禁
- LINUX怎么设置系统语言_LINUX修改中文环境
- Win11右键反应慢怎么办 Win11优化右键菜单
- Mac怎么给文件夹加密_Mac创建加密磁盘映像教程
- php增删改查报错1054怎么办_字段名错误排查修
- Django 密码修改后会话失效的解决方案
- php转mp4怎么设置帧率_调整php生成mp4视
- 如何处理“XML格式不正确”错误 常见XML we
- Win11蓝牙开关不见了怎么办_Win11蓝牙驱动
- 如何提升Golang程序I/O性能_Golang
- 如何使用Golang实现云原生应用弹性伸缩_自动应
- Win11如何设置系统声音_Win11系统声音调整
- Win11麦克风没声音怎么设置_Win11麦克风权
- 如何解决同一段404代码在不同主机上表现不一致的问
- php485在php5.6下能用吗_php485旧
- Win11怎么设置任务栏大小_Windows11注
- php文件怎么变mp4保存_php输出视频流保存为
- Win10如何更改用户账户控制_Windows10
- Win10系统更新错误0x80240034怎么办
- Win11声音忽大忽小怎么办 Win11音频增强功
- php中::能访问全局变量吗_全局作用域与类作用域
- php打包exe后无法写入文件_权限问题解决方法【
- php485返回数据不完整怎么办_php485数据
- 如何使用Golang实现容器安全扫描_Golang
- Win10系统怎么查看网络连接状态_Windows
- c# F# 的 MailboxProcessor
- Windows10电脑怎么查看硬盘通电时间_Win
- Linux如何使用grep搜索文件内容_Linux
- Windows10如何更改计算机工作组_Win10
- SAX解析器是什么,它与DOM在处理大型XML文件
- Mac如何使用听写功能_Mac语音输入打字【效率技
- Windows10蓝屏代码DPC_WATCHDOG
- Win11任务栏怎么放到顶部_Win11修改任务栏
- 小程序里php怎么变mp4_小程序调用php生成m

phone', '').strip()
message = request.form.get('message', '').strip()
# 基础验证(可选但推荐)
if not all([name, email, message]):
flash('Please fill in all required fields.', 'error')
return render_template('contact.html', msg_sent=False)
# ✅ 关键:显式调用 send_email 并检查结果
if send_email(name, email, phone, message):
flash('Your message has been sent successfully!', 'success')
return render_template('contact.html', msg_sent=True)
else:
flash('Failed to send email. Please try again later.', 'error')
return render_template('contact.html', msg_sent=False)
# GET 请求:渲染空表单
return render_template('contact.html', msg_sent=False)
QQ客服