Flask POST请求读取request.form触发400 Bad Request问题排查
问题根因
这个报错和代码缩进没有任何关系,核心原因是Flask的request.form参数解析对象,在直接使用方括号[]访问不存在的键时,框架会自动返回400 Bad Request响应,不会执行后续分支代码,也不会在控制台抛出普通KeyError对应的500错误栈。
你的页面写了两个完全独立的form表单,提交任意一个表单时,请求只会携带当前表单内部的字段,不会包含另一个表单的字段:
- 点击
Submit post按钮提交第一个表单时,请求体只会携带name、post、submit_post三个字段,不存在print_posts字段 - 点击
Print posts按钮提交第二个表单时,请求体只会携带print_posts一个字段,不存在submit_post字段
你遇到的「调换判断顺序就换一个按钮失效」的现象完全符合这个逻辑:
- 原代码先判断
submit_post,点print_posts按钮提交时,第一个if分支就尝试访问不存在的submit_post键,直接触发400,根本走不到后面的elif分支 - 把
print_posts判断移到最前面后,点submit_post按钮提交时,第一个if分支就尝试访问不存在的print_posts键,再次触发400,就变成submit_post分支失效。
修复方案
两种常用写法任选其一即可,不需要修改前端HTML结构:
方案1:用.get()方法读取表单字段
字典的.get()方法访问不存在的键时不会报错,只会返回None(也可以自定义默认值),不会触发400:
if request.method == 'POST': if request.form.get('submit_post') == 'Submit post': print('Hello') # 此处编写提交新帖子的业务逻辑 elif request.form.get('print_posts') == 'Print posts': print('Print all posts') # 此处编写查询打印所有帖子的业务逻辑 else: print("malformed request")
方案2:先校验字段存在再取值
用in关键字先判断提交的表单里是否包含对应字段,再做值校验:
if request.method == 'POST': if 'submit_post' in request.form and request.form['submit_post'] == 'Submit post': print('Hello') # 提交新帖子逻辑 elif 'print_posts' in request.form and request.form['print_posts'] == 'Print posts': print('Print all posts') # 打印所有帖子逻辑 else: print("malformed request")
内容的提问来源于stack exchange,提问作者Ethan T
相关产品推荐
相关产品推荐

