2012-08-19 8 views
10

Ich schreibe eine Web-App mit Kolben, Python und HTML. Mein Problem ist, dass das erste Mal, dass ich die eine Webseite laden, bekomme ich folgende FehlerBad Request Error mit Kolben, Python, HTML, ungewöhnliches Initialisierungsverhalten mit flask.request.form

Bad Request Der Browser (oder Proxy) eine Anfrage erhalten hat, dass dieser Server nicht verstehen kann.

Ich bin in der Lage, die Seite zu bekommen schließlich von „austricksen“ zuerst laden ohne flask.request.form Anrufe läuft, und sie dann wieder in (Details unten) setzen. Bei meiner Initialisierung muss etwas schief gehen. Ich bin neu in flask und mit python mit HTML.

Angenommen, ich arbeite von einem Verzeichnis namens example. Ich habe ein Python-Skript test.py und ein HTML-Template namens test.html mit der folgenden Verzeichnisstruktur genannt:

\example\test.py 
\example\templates\test.html 

Mein Python-Skript test.py ist:

import sys 
import flask, flask.views 
app = flask.Flask(__name__) 
app.secret_key = "bacon" 

class View(flask.views.MethodView): 
    def get(self): 
     result = flask.request.form['result'] 
     return flask.render_template('test.html', result=result) 
#  return flask.render_template('test.html') 
    def post(self): 
     return self.get() 

app.add_url_rule('/', view_func=View.as_view('main'), methods=['GET', 'POST']) 
app.debug = True 
app.run() 

und mein HTML in test.html ist

<html> 
    <head> 
    </head> 
    <body> 
     <form action="/" method="post"> 
      Enter something into the box: 
      <input type="text" name="result"/><br> 
      <input type="submit" value="Execute!"/> 
     </form> 
    </body> 
</html> 

Schritte zum Reproduzieren des Fehlers

1: Führen Sie das test.py Skript, und öffnen Sie die URL in einem Browser auf

Running on http://127.0.0.1:5000/ 

Sie sollten die folgenden Fehler

Bad Request Der Browser (oder Proxy) sehen schickte eine Anfrage, dass Dieser Server konnte nicht verstehen.

2: die ersten zwei Zeilen der def get(self) Funktion Kommentar und die dritte Zeile der def get(self) Funktion Kommentar-, so dass test.py wie diese

import sys 
import flask, flask.views 
app = flask.Flask(__name__) 
app.secret_key = "bacon" 

class View(flask.views.MethodView): 
    def get(self): 
#  result = flask.request.form['result'] 
#  return flask.render_template('test.html', result=result) 
     return flask.render_template('test.html') 
    def post(self): 
     return self.get() 

app.add_url_rule('/', view_func=View.as_view('main'), methods=['GET', 'POST']) 
app.debug = True 
app.run() 

3 aussieht: Aktualisieren Sie die URL, und Sie werden sehen, dass die Dinge funktionieren (obwohl ich den Wert von result

4 zurückzukehren schließlich in der Lage sein wollen: Nun wechseln die Zeilen, die wieder auf Kommentar werden Dh, Kommentar- der ersten 2 Zeilen der def get(self) Funktion und commen. t die dritte Zeile der def get(self) Funktion, so dass test.py wie diese

import sys 
import flask, flask.views 
app = flask.Flask(__name__) 
app.secret_key = "bacon" 

class View(flask.views.MethodView): 
    def get(self): 
     result = flask.request.form['result'] 
     return flask.render_template('test.html', result=result) 
#  return flask.render_template('test.html') 
    def post(self): 
     return self.get() 

app.add_url_rule('/', view_func=View.as_view('main'), methods=['GET', 'POST']) 
app.debug = True 
app.run() 

5 aussieht: Aktualisieren Sie die URL und jetzt sehen Sie die Dinge wie gewünscht arbeiten.

Dies ist nur ein Spielzeugbeispiel, das das wirkliche Problem darstellt, dieses seltsame Verhalten zu zeigen, wie ich meinen Browser "tricksen" muss, um mir diese Webseite zu zeigen.Die

Antwort

27

Das Problem hier ist, dass Sie versuchen, auf POST ED-Variablen in einer Methode zuzugreifen, die nur GET Anforderungen behandelt. Wenn Sie versuchen, auf eine Abfragezeichenfolge oder einen POST-Parameter zuzugreifen, der nicht auf Flask will, by default, raise a BadRequest error festgelegt ist (weil Sie nach etwas fragen, das die Person, die die Seite trifft, nicht angegeben hat).

Was passiert, wenn der Schlüssel nicht im Formularattribut vorhanden ist? In diesem Fall wird ein spezieller KeyError ausgelöst. Sie können es wie einen Standard-KeyError abfangen, aber wenn Sie dies nicht tun, wird stattdessen eine HTTP 400 Bad Request-Fehlerseite angezeigt. In vielen Situationen müssen Sie sich nicht mit diesem Problem befassen.

Wenn Sie von einer Variable für den Zugriff auf entweder request.args (GET) oder request.form (POST) und Sie nicht Notwendigkeit es stellen Sie die get-Methode verwenden, um den Wert zu erhalten, wenn es da ist (oder . None wenn er nicht gesetzt ist

# Will default to None 
your_var = request.form.get("some_key") 

# Alternately: 
your_var = request.form.get("some_key", "alternate_default_value") 

Hier ist eine alternative Art und Weise Ihren Code strukturieren:

import sys 
import flask, flask.views 

app = flask.Flask(__name__) 

app.secret_key = "bacon" 
app.debug = True 


class View(flask.views.MethodView): 
    def get(self): 
     """Enable user to provide us with input""" 
     return self._default_actions() 

    def post(self): 
     """Map user input to our program's inputs - display errors if required""" 
     result = flask.request.form['result'] 
     # Alternately, if `result` is not *required* 
     # result = flask.request.form.get("result") 
     return self._default_actions(result=result) 

    def _default_actions(self, result=None): 
     """Deal with the meat of the matter, taking in whatever params we need 
     to get or process our information""" 
     if result is None: 
      return flask.render_template("test.html") 
     else: 
      return flask.render_template("test.html", result=result) 

app.add_url_rule('/', view_func=View.as_view('main'), methods=['GET', 'POST']) 

if __name__ == "__main__": 
    app.run() 
+0

genial Danke für die tolle Erklärung ! – erin

+0

Dies ist eine großartige Erklärung, wie Standardanforderungen in Flask implementiert werden. Vielen Dank. – earthmeLon

+0

Ich verwende die Flask-App auf einem Apache-Server. Egal was ich mache, bekomme ich einen fehlerhaften Anforderungsfehler. 'Der Browser hat eine Antwort gesendet' usw. Hat das etwas mit meinem Server zu tun? –