10

フラスコ、Python、HTMLを使用してWebアプリを作成しています。私の問題は、Webページを初めてロードするときに、次のエラーが発生することです。

不正なリクエストブラウザ(またはプロキシ)が、このサーバーが理解できないリクエストを送信しました。

最初に呼び出しなしでページを「トリック」して実行しflask.request.form、次にそれらを元に戻すことで、最終的にページをロードすることができます(詳細は以下を参照)。初期化で問題が発生している可能性があります。私は初めてでflask、で使用pythonしていHTMLます。

と呼ばれるディレクトリから作業していると仮定しexampleます。と呼ばれるPythonスクリプトと、次のディレクトリ構造でtest.py呼び出されるHTMLテンプレートがあります。test.html

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

私のPythonスクリプトtest.pyは次のとおりです。

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()

私のHTMLtest.html

<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>

エラーを再現する手順

1:test.pyスクリプトを実行し、ブラウザでURLを開きます

Running on http://127.0.0.1:5000/

次のエラーが表示されます

不正なリクエストブラウザ(またはプロキシ)が、このサーバーが理解できないリクエストを送信しました。

2:関数の最初の2行をコメントアウトし、関数def get(self)の3行目のコメントを外して次のようにします。def get(self)test.py

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:URLを更新すると、動作することがわかります(ただし、最終的にはresult

4:ここで、コメントアウトされた行を再度切り替えます。つまり、関数の最初の2行のコメントを解除し、関数def get(self)の3行目をコメントアウトして次のようにします。def get(self)test.py

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:URLを更新すると、希望どおりに機能していることがわかります。

これは、ブラウザを「だまして」このWebページを表示させるという奇妙な動作を示す実際の問題を示すおもちゃの例にすぎません。The

4

1 に答える 1

28

The issue here is that you are attempting to access POSTed variables in a method that will only handle GET requests. When you attempt to access a query string or POST parameter that is not set Flask will, by default, raise a BadRequest error (because you are asking for something that the person hitting the page did not supply).

What happens if the key does not exist in the form attribute? In that case a special KeyError is raised. You can catch it like a standard KeyError but if you don’t do that, a HTTP 400 Bad Request error page is shown instead. So for many situations you don’t have to deal with that problem.

If you need to access a variable from either request.args (GET) or request.form (POST) and you don't need it to be set use the get method to get the value if it is there (or None if it is not set.

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

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

Here's an alternate way of structuring your code:

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()
于 2012-08-19T03:01:08.123 に答える