为什么向瓶中的函数添加请求会在空POST中导致“错误请求”?
在为我的Flask应用程序进行测试时,我偶然发现了我无法理解的行为。在我的测试中,我使用Flask documentation建议的方法来访问和修改测试中的session
。为什么向瓶中的函数添加请求会在空POST中导致“错误请求”?
说我有,很基本的,项目结构:
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 ''
会解决问题,但它不会。一个简单的办法来,这是一些存根data
添加到发布请求,像这样response = client.post('/action/', data=dict(action='stub'))
这种感觉对我来说,我错过了一些重要的点上如何访问&自考工作会议修改,因此我无法理解所描述的行为。
我想了解的是:
- 为什么仅仅让从请求数据不添加任何其他逻辑(即线
the_action = request.form['action']
造成的空POST
-
400 Bad Request
响应为什么不会the_action = request.form['action'] or ''
或the_action = request.form['action'] or 'stub'
解决这个问题,在我看来情况就好像是空字符串或'stub'
是通过POST
发送的?
Ba通过chris和answer to the linked question的sed的意见,我现在看到这个问题,基本上的What is the cause of the Bad Request Error when submitting form in Flask application?
从当前问题解决的问题点重复:
- 如果瓶是无法从
args
或form
字典中找到任何密钥,则会引发HTTP错误(本例中为400 Bad Request
)。无论以任何方式获取密钥影响应用的逻辑(即仅将其分配给变量the_action = request.form['action']
将导致HTTP错误,如果action
密钥不存在于form
中)。
这是由Sean Vieira总结了了评论linked question:当它无法找到在指定参数和形式字典的关键
瓶引发的HTTP错误。
-
the_action = request.form['action'] or ''
或the_action = request.form['action'] or 'stub'
是不够的,因为瓶将尝试在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
错误。
也许我错过了什么,你在哪里设置你发布的数据? – chrisz
您提到一个简单的解决方法是将虚拟数据添加到发布请求中。如果您试图从数据请求中提取数据,则需要将数据放入。 – chrisz
@chris我明白为了将数据提取出来需要先将其发布出来,这里有什么令我困惑的是_(因为它在我看来,至少)_我没有真正拉出任何东西,只是将值分配给变量(即'the_action = request.form ['action']')。由于它不影响'action'返回逻辑_(它只是坐在那里)的任何部分,所以我不明白为什么'400 Bad Request'被返回。 –