Was ist die Ursache für den Fehler "Bad Request" beim Senden des Formulars in der Flask-Anwendung?

79

Nachdem ich viele ähnlich klingende Probleme und die relevanten Flask-Dokumente gelesen habe, kann ich anscheinend nicht herausfinden, was beim Senden eines Formulars den folgenden Fehler erzeugt:

400 schlechte Anfrage

Der Browser (oder Proxy) hat eine Anfrage gesendet, die dieser Server nicht verstehen konnte.

Während das Formular immer richtig angezeigt wird, tritt die fehlerhafte Anforderung auf, wenn ich ein HTML-Formular sende, das mit einer der folgenden Funktionen verknüpft ist:

@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")

Der relevante Teil von HTML ist

<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="[email protected]">
    ...

Das Problem für die meisten Leute war nicht anzurufen GEToder POST, aber ich mache genau das in beiden Funktionen, und ich habe noch einmal überprüft, ob ich alles Notwendige importiert habe, wie z from flask import request. Ich habe auch die Datenbank abgefragt und bestätigt, dass die Ergänzungen aus dem Formular nicht hinzugefügt wurden.

In der Flask-App habe ich Formularfelder angefordert, die im HTML-Formular leicht unterschiedlich gekennzeichnet waren. Die Namen konsistent zu halten ist ein Muss. Weitere Informationen finden Sie unter dieser Frage. Fehler beim Senden des Formulars, Flasche

zch
quelle
@ SeanVieira habe ich; Obwohl er denselben Fehler verursachte, schien das Problem darauf zurückzuführen zu sein, dass er versuchte, ein Formular über zwei verschiedene Schaltflächen auf derselben Seite zu senden - das Problem bestand darin, zwischen den beiden zu unterscheiden -, während ich nur eine einzige Schaltfläche habe, die einen POST aufruft.
zch
5
Chuckles Sorry, hätte klarer sein sollen - "Flask löst einen HTTP-Fehler aus, wenn es keinen Schlüssel in den Argumenten und Formularwörterbüchern findet" - eines der Felder, auf die Sie zugreifen möchten, request.formist nicht vorhanden (z. B. Sie senden name_feildund suchen für name_field- beachten Sie die falsche Schreibweise), also den Fehler. (Die Einstellung app.debug = Truehilft Ihnen, den Fehler zu finden).
Sean Vieira

Antworten:

135

Die Lösung war einfach und in den Kommentaren aufgedeckt. Wie in dieser Frage angesprochen, Form Sendefehler, Flask , und von Sean Vieira darauf hingewiesen ,

... das Problem ist, dass Flask einen HTTP-Fehler auslöst, wenn es keinen Schlüssel in den Argumenten und Formularwörterbüchern findet. Was Flask standardmäßig annimmt, ist, dass, wenn Sie nach einem bestimmten Schlüssel fragen und dieser nicht vorhanden ist, etwas aus der Anfrage herausgelassen wurde und die gesamte Anfrage ungültig ist.

Mit anderen Worten, wenn nur ein Formularelement, das Sie in Python anfordern, nicht in HTML gefunden werden kann, ist die POST-Anforderung ungültig und der Fehler wird angezeigt, in meinem Fall ohne Unregelmäßigkeiten im Traceback. Für mich war es ein Mangel an Übereinstimmung mit der Rechtschreibung: Im HTML habe ich verschiedene Formulareingaben beschriftet

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

Während in Python ein POST aufgerufen wurde, greife ich zu einem nicht vorhandenen Formular mit

request.form['question1']

Um mit meinen HTML-Formularnamen übereinstimmen zu können, musste dies der Fall sein

request.form['question1_field']

Ich hoffe das hilft.

zch
quelle
11
Sie können auchrequest.form.get('key', default_value)
OdraEncoded
1
@OdraEncoded Ihre Lösung hat das Problem behoben. Ich habe nicht daran gedacht, sondern dict.get()zurückgegeben, Nonewas sicherer ist als der direkte Zugriff mit dem Schlüssel, was KeyErrordie App verursachen und damit zum Absturz bringen kann.
Pie 'Oh' Pah
<input name = "must_match">
jasonleonhard