首页 > 解决方案 > 如何通过 POST 向 Flask 应用程序发送和接收显式空值

问题描述

我正在尝试找到一种方法,通过 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 编码的请求和其他未编码的请求似乎不一致。

标签: pythonpostflasknull

解决方案


问题出在您的 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__)

推荐阅读