使用flask.request.form,烧瓶,python,HTML,异常初始化行为的错误请求错误

eri*_*rin 10 html python bad-request flask

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

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

我可以通过"欺骗"首先运行它而不需要任何flask.request.form调用,然后将它们放回(下面的详细信息)中来最终加载页面.我的初始化必定会出错.我是新来的flask,并使用pythonHTML.

假设我正在使用一个名为的目录example.我有一个调用的python脚本test.py和一个test.html使用以下目录结构调用的HTML模板:

\example\test.py
\example\templates\test.html
Run Code Online (Sandbox Code Playgroud)

我的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()
Run Code Online (Sandbox Code Playgroud)

我的HTML test.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>
Run Code Online (Sandbox Code Playgroud)

重现错误的步骤

1:运行test.py脚本,并在浏览器中打开URL

Running on http://127.0.0.1:5000/
Run Code Online (Sandbox Code Playgroud)

您应该看到以下错误

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

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()
Run Code Online (Sandbox Code Playgroud)

3:刷新URL,你会发现事情有效(尽管我最终希望能够返回值) result

4:现在,再次切换注释掉的行.即,取消注释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()
Run Code Online (Sandbox Code Playgroud)

5:刷新URL,现在您可以看到所需的内容.

这只是一个玩具示例,说明真正的问题,表现出我必须"欺骗"我的浏览器向我显示这个网页的这种奇怪的行为.该

Sea*_*ira 28

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

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

如果您需要从任何访问变量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")
Run Code Online (Sandbox Code Playgroud)

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

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()
Run Code Online (Sandbox Code Playgroud)