我正在尝试找到一种方法,通过 POST 方法将具有显式空值的字段(而不是空字符串值或请求中没有字段本身(从我的 UI 发送到我的 Flask 应用程序后端。后者似乎将我通过 AJAX 发送的空值解释为空字符串。
到目前为止,我正在从UI发送我的AJAX请求,如下所示:
$.ajax({
type: 'POST',
url: SOME_URL,
data: {
foo: null
},
success: function() {
// process response
}
});
以下是 Flask 中发生的事情:
if request.form.get('foo') is None:
# Happens only if 'foo' field was not included in the request
return response('Got None')
elif request.form.get('foo') == '':
# Happens for empty string or null sent as value of 'foo'
return response('Got empty string')
显然,可以对 POST 数据进行 JSON 编码,然后在服务器上对其进行解码,从而保留空值。有没有更优雅的方法可以做到这一点?首先,我认为使用WTForms进行验证会变得更加困难。发送一些 JSON 编码的请求而发送其他未编码的请求似乎不一致。
问题出在你的 ajax 调用中。默认情况下,$.ajax
作为application/x-www-form-urlencoded
数据发送。例如:
{
a: 'foo',
b: 'bar',
c: 'baz',
d: null,
e: ''
}
由 jQuery 转换为:
a=foo&b=bar&c=baz&d=&e=
jQuery似乎将null
强制为空字符串,因此它确实发送了一个空字符串。没有 JSON。
要使jQuery不这样做,请自己将其字符串化:
$.ajax({
type: 'POST',
url: SOME_URL,
// Send a JSON string (NOT an object)
data: JSON.stringify({
foo: null
}),
// Tell Flask that it is a JSON string, so Flask parses as JSON
contentType: 'application/json; charset=utf-8',
success: function() {
// process response
}
});
作为旁注,你应该在Python中这样做:
data = request.get_json()
if 'foo' not in data:
# 'foo' does not exist
elif data['foo'] is None:
# 'foo' exists and is (js) null (python) None
elif data['foo'] == '':
# it is the empty string
或者可能是这样的:
try:
foo = data['foo']
except KeyError:
# Handle no 'foo' key
else:
if foo is None:
# Handle None case
elif isinstance(foo, str):
# Handle string case
else:
logger.warn('[%s] foo is not a string or None, and instead %s', flask_session_info(), type(foo).__name__)