【问题标题】:Why adding request to a function in flask, causes 'Bad Request' on empty POST?为什么向烧瓶中的函数添加请求会导致空 POST 出现“错误请求”?
【发布时间】:2017-10-21 06:42:23
【问题描述】:

在为我的 Flask 应用程序进行测试时,我偶然发现了一些我不太理解的行为。在我的测试中,我使用Flask documentation 建议的方法从测试中访问和修改session

假设我有一个非常基本的项目结构:

root
|-- my_app.py
|-- tests
    |-- test_my_app.py

my_app.py

from flask import (
    Flask,
    session,
    request
    )

app = Flask(__name__)
app.secret_key = 'bad secret key'

@app.route('/action/', methods=['POST'])
def action():
    the_action = request.form['action']
    if session.get('test'):
        return 'Test is set, action complete.'
    else:
        return 'Oy vey!'

test_my_app.py

import flask

from unittest import TestCase
import my_app

class TestApp(TestCase):

    def setUp(self):
        self.test_client = my_app.app.test_client()

    def testUnsetKeyViaPostNegative(self):
        with self.test_client as client:
            response = client.post('/action/')
            expected_response = 'Oy vey!'.encode('ascii')
            self.assertTrue(expected_response == response.data)

现在,如果我运行测试,它将失败,因为响应返回 400 Bad Request。如果the_action = request.form['action'] 被表扬,一切顺利。

我需要它的原因是因为应用程序中有一个逻辑(以及随后的测试),这取决于收到的data(为简洁起见,我省略了)。

我认为将the_action = request.form['action'] 更改为the_action = request.form['action'] or '' 可以解决问题,但它不会。一个简单的解决方法是在 post 请求中添加一些存根 data,就像这样 response = client.post('/action/', data=dict(action='stub'))

在我看来,我错过了一些关于如何从测试中访问和修改会话的重要观点,因此我无法理解所描述的行为。

我想了解的是:

  1. 为什么只是从请求中获取数据而不添加任何其他逻辑(即行 the_action = request.form['action'] 导致 400 Bad Request 响应空 POST
  2. 为什么the_action = request.form['action'] or ''the_action = request.form['action'] or 'stub' 不能解决问题,在我看来好像是空字符串或'stub' 是通过POST 发送的?

【问题讨论】:

  • 也许我遗漏了什么,你在哪里设置你发布的数据?
  • 您提到一个简单的解决方法是在发布请求中添加虚拟数据。如果您尝试从 post 请求中提取数据,则需要将数据放入。
  • @chris 我知道为了提取数据,我需要先将其发布,这里让我感到困惑的是 (至少在我看来) 我并没有真正拿出任何东西,只是将值分配给变量(即the_action = request.form['action'])。由于它不影响action 返回逻辑的任何部分(它只是坐在那里),我不明白为什么会返回400 Bad Request
  • "...问题是 Flask 在 args 和表单字典中找不到键时会引发 HTTP 错误。默认情况下,Flask 假设如果您要求特定键并且它不存在,然后请求中遗漏了某些内容,整个请求无效。”来自this答案

标签: python flask request http-post


【解决方案1】:

基于chrisanswer to the linked question 的cmets,我现在看到这个问题基本上是What is the cause of the Bad Request Error when submitting form in Flask application? 的重复项


解决当前问题中的问题点:

  1. 如果 Flask 无法从 argsform 字典中找到任何键,则会引发 HTTP 错误(在这种情况下为 400 Bad Request)。不管获取密钥是否会以任何方式影响应用程序的逻辑(即,如果 form 中不存在 action 密钥,则仅将其分配给变量 the_action = request.form['action'] 将导致 HTTP 错误)。

Sean Vieiralinked question 的评论总结了这一点:

Flask 在 args 和表单字典中找不到键时会引发 HTTP 错误。

  1. the_action = request.form['action'] or ''the_action = request.form['action'] or 'stub' 是不够的,因为 Flask 将尝试在 request.form['action'] 中获取不存在的密钥,但由于它不存在而失败并导致 400 Bad Request,然后才会到达 or。话虽如此 - or 永远不会到达 好像 request.form['action'] 有一个值 - the_action 将被分配给这个值,否则 400 Bad Request 将被返回。

为避免这种情况 - 应使用字典的 get() 方法,同时将默认值传递给它。所以the_action = request.form['action'] or 'stub' 变成了the_action = request.form.get('action', 'stub')。这样,空 POST 不会导致 400 Bad Request 错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-17
    • 2020-08-24
    • 1970-01-01
    • 2017-06-02
    • 1970-01-01
    • 2014-07-23
    • 1970-01-01
    相关资源
    最近更新 更多