当在Flask应用程序中提交表单时,导致“Bad Request Error”的原因是什么?

91

阅读了许多类似的问题和相关的Flask文档后,我似乎无法弄清楚是什么导致在提交表单时生成以下错误:

400 Bad Request

The browser (or proxy) sent a request that this server could not understand.

虽然表单始终正确显示,但当我提交连接到这些函数之一的HTML表单时,就会出现错误请求:

@app.route('/app/business', methods=['GET', 'POST'])
def apply_business():
    if request.method == 'POST':    
        new_account = Business(name=request.form['name_field'], email=request.form['email_field'], account_type="business", 
            q1=request.form['q1_field'], q2=request.form['q2_field'], q3=request.form['q3_field'], q4=request.form['q4_field'], 
            q5=request.form['q5_field'], q6=request.form['q6_field'], q7=request.form['q7_field'],
            account_status="pending", time=datetime.datetime.utcnow())
        db.session.add(new_account)
        db.session.commit()
        session['name'] = request.form['name_field']    
        return redirect(url_for('success'))
    return render_template('application.html', accounttype="business")          

@app.route('/app/student', methods=['GET', 'POST'])
def apply_student():    
    if request.method == 'POST':    
        new_account = Student(name=request.form['name_field'], email=request.form['email_field'], account_type="student", 
            q1=request.form['q1_field'], q2=request.form['q2_field'], q3=request.form['q3_field'], q4=request.form['q4_field'], 
            q5=request.form['q5_field'], q6=request.form['q6_field'], q7=request.form['q7_field'], q8=request.form['q8_field'], 
            q9=request.form['q9_field'], q10=request.form['q10_field'],
            account_status="pending", time=datetime.datetime.utcnow())
        db.session.add(new_account)
        db.session.commit()
        session['name'] = request.form['name_field']    
        return redirect(url_for('success')) 
    return render_template('application.html', accounttype="student")

相关的HTML部分是

<html>
<head>
    <title>apply</title>
</head>
<body>
    {% if accounttype=="business" %}
    <form action="{{ url_for('apply_business') }}" method=post class="application_form">
    {% elif accounttype=="student" %}
    <form action="{{ url_for('apply_student') }}" method=post class="application_form">     
    {% endif %} 
    <p>Full Name:</p>
    <input name="name_field" placeholder="First and Last">
    <p>Email Address:</p>
    <input name="email_field" placeholder="your@email.com">
    ...

对大多数人来说,问题并不在于调用GETPOST方法,而是我在这两个函数中都这样做了,并且我已经仔细检查了是否导入了所有必要的内容,例如from flask import request。我还查询了数据库并确认表单中的添加未被添加。

在Flask应用程序中,我请求的表单字段在HTML表单中标记略有不同。保持名称一致是必须的。更多信息可以阅读这个问题:Form sending error, Flask


你看过 https://dev59.com/LWoy5IYBdhLWcg3wcNlO 吗? - Sean Vieira
@SeanVieira 我已经尝试过了,虽然出现了相同的错误,但问题似乎是由于他试图从同一页上的两个不同按钮提交表单而引起的 - 问题在于区分这两个按钮 - 而我只有一个调用POST的单个按钮。 - zch
6
轻笑 抱歉,我应该更清楚 - "当Flask在args和form字典中找不到键时,会引发HTTP错误" - 你试图在 request.form 中访问的字段之一不存在(例如,你发送了 name_feild ,但正在寻找 name_field - 注意拼写错误),因此会出现错误。(设置app.debug = True将帮助你找到错误)。 - Sean Vieira
1个回答

145

解决方案很简单,评论中揭示了答案。就像在这个问题Form sending error, Flask所述,并且由Sean Vieira指出的那样,

... 问题在于,当 Flask 在 args 和 form 字典中找不到键时会引发 HTTP 错误。Flask 默认情况下的假设是,如果您请求特定的键但未找到该键,则请求中遗漏了某些内容,整个请求无效。

换句话说,如果在 Python 中请求的表单元素在 HTML 中找不到,那么 POST 请求就无效了,并且错误会出现,就像我的情况一样,在 traceback 中没有任何异常。对我而言,问题在于拼写不一致:在 HTML 中,我标记了各种形式的表单输入。

<input name="question1_field" placeholder="question one">

在Python中,当有一个POST被调用时,我使用一个不存在的表单来获取它。

request.form['question1']

然而,为了与我的HTML表单名称保持一致,它需要被这样处理。

request.form['question1_field']

13
你可以使用 request.form.get('key', default_value) 进行获取,其中default_value为默认值。 - OdraEncoded
1
@OdraEncoded 你的解决方案修复了问题。我没有想到,但是 dict.get() 返回 None,这比直接使用键访问更安全,因为后者可能会导致 KeyError 并崩溃应用程序。 - Pandemonium
<input name="must_match"> - jasonleonhard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接