10

我正在使用烧瓶、python 和 HTML 编写一个网络应用程序。我的问题是第一次加载网页时,出现以下错误

错误请求 浏览器(或代理)发送了此服务器无法理解的请求。

我能够通过“欺骗”首先在没有任何flask.request.form调用的情况下运行它,然后将它们放回原处来最终加载页面(详情如下)。我的初始化一定有问题。我是新手flask并使用pythonwith 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脚本,在浏览器中打开网址

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,现在您会看到一切正常。

这只是一个玩具示例,说明了展示这种奇怪行为的真正问题,即我必须如何“欺骗”我的浏览器向我展示这个网页。这

4

1 回答 1

28

这里的问题是您试图POST在仅处理GET请求的方法中访问 ed 变量。当您尝试访问未设置的查询字符串或 POST 参数时,默认情况下,Flask 会引发BadRequest错误(因为您正在要求访问页面的人没有提供的内容)。

如果表单属性中不存在键会怎样?在这种情况下,会引发特殊的 KeyError。您可以像标准的 KeyError 一样捕获它,但如果您不这样做,则会显示 HTTP 400 Bad Request 错误页面。因此,在许多情况下,您不必处理该问题。

如果您需要从request.args(GET) 或request.form(POST) 访问变量并且不需要设置它,请使用该get方法获取值(如果它存在)(或者None如果它未设置。

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

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

这是构建代码的另一种方法:

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