【问题标题】:Accessing incoming POST data in Flask在 Flask 中访问传入的 POST 数据
【发布时间】:2018-06-24 16:29:13
【问题描述】:

这是烧瓶代码:

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}

docs 似乎非常清楚这应该可以工作:

表格

带有来自 POST 或 PUT 请求的已解析表单数据的 MultiDict。 请记住,文件上传不会在这里结束,但 而是在 files 属性中。

参数

具有查询字符串的解析内容的 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

【问题讨论】:

  • curl -X GET 发送一个 GET 请求...你需要 curl -X POST
  • 谢谢,但没有帮助。我明确想在请求正文中发送带有 JSON 的 GET。
  • 你试过request.get_json()而不是request.values,因为如果你设置Content-Type: application/json header,它就可以工作。
  • request.json 提供解析的字典,而不是字符串,这就是 json.load 失败的原因。我还错误地指出 POST 原始文本正文存储在 request.body 中,而它实际上存储在 request.data 中。原始答案已更新以更正此问题。
  • 啊。我怀疑这也会导致问题,但由于错误是“NoneType..”,问题似乎不是json.load 正在尝试加载字典,而是它正在尝试加载None。不管怎样,我的问题已经解决了。

标签: python curl flask


【解决方案1】:

您无意中发送了错误的Content Type

默认情况下,curl's -d flag will send POST data with content-type 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 form data,不包含其他内容类型。您可以使用 request.data 访问原始 POST 请求正文,或者更方便的是使用 request.get_json 访问解析的 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 is deprecatedrequest.get_json。原帖已更新。

【讨论】:

  • 有效。但是,我现在更讨厌 Flask(和 Python)了。它对事情应该如何发展有强烈的、无证的意见,并且对学习这些意见不抱歉意或善意。无论如何,谢谢,@jtimmons
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多