一尘不染

在Flask中访问传入的POST数据

flask

这是flask代码:

from flask import Flask, request
import json
app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def refresh():
    params = {
        'thing1': request.values.get('thing1'),
        'thing2': request.values.get('thing2')
    }
    return json.dumps(params)

这是cURL

$ curl -XGET 'http://127.0.0.1:5000/?thing1=1' -d '{"thing2":2}'                                              
> {"thing1": "1", "thing2": null}

$ curl -XGET 'http://127.0.0.1:5000/?thing1=1' -d '{"thing2":2}'                                              
> {"thing1": "1", "thing2": null}

该文档似乎非常清楚这应该工作:

形成

包含来自POST或PUT请求的已解析表单数据的MultiDict。请记住,文件上传不会在此处结束,而是在files属性中结束。

args

具有查询字符串的已解析内容的MultiDict。(URL中问号后的部分)。

价值观

一个同时包含form和args内容的CombinedMultiDict。

有什么想法我做错了吗?

更新:尝试从答案之一中提出建议,换return行:

使用会return json.dumps(json.load(request.body.decode("utf-8") ))产生错误AttributeError: 'Request' object has no attribute 'body'

使用会return json.dumps(json.load(request.json))产生错误AttributeError: 'NoneType' object has no attribute 'read'

使用POST与原点代码出现没有任何效果:

$ curl -XPOST 'http://127.0.0.1:5000/?thing1=1' -d '{"thing2":2}'
{"thing1": "1", "thing2": null}

设置内容类型并POST与原始代码一起使用也没有明显的效果:

$ curl -XPOST -H "Content-Type: application/json" 'http://127.0.0.1:5000/?thing1=1' -d '{"thing2":2}' 
{"thing1": "1", "thing2": null}

尽管我去验证了内容类型是否正确设置:

...
print(request.headers)
...

Host: 127.0.0.1:5000
User-Agent: curl/7.54.0
Accept: */*
Content-Type: application/json
Content-Length: 12

阅读 557

收藏
2020-04-08

共1个答案

一尘不染

你无意间发送了错误的Content Type。

默认情况下,curl的-d标志将发送content-type的POST数据application/x-www-form-urlencoded。由于你没有以期望的格式(key = value)发送数据,因此它将完全删除数据。对于JSON数据,你需要发送内容类型设置为application/json如下的HTTP请求:

curl -XPOST -H "Content-Type: application/json" 'http://127.0.0.1:5000/?thing1=1' -d '{"thing2":2}'

另外,flask的request.form字段仅包含POST表单数据,而不包含其他内容类型。你可以使用request.data或更方便地使用解析的JSON数据访问原始POST请求主体request.get_json

下面是示例的固定版本:

from flask import Flask, request
import json
app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def refresh():
    params = {
        'thing1': request.values.get('thing1'),
        'thing2': request.get_json().get('thing2')
    }
    return json.dumps(params)


app.run()

更新:我之前打错了 request.body实际上应该是request.data。事实证明request.json它已被弃用,request.get_json现在应改为使用。原始帖子已更新。

2020-04-08