Python 如何在 Flask 中获取 POSTed JSON?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20001229/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 19:13:32  来源:igfitidea点击:

How to get POSTed JSON in Flask?

pythonjsonpostflask

提问by kramer65

I'm trying to build a simple API using Flask, in which I now want to read some POSTed JSON. I do the POST with the Postman Chrome extension, and the JSON I POST is simply {"text":"lalala"}. I try to read the JSON using the following method:

我正在尝试使用 Flask 构建一个简单的 API,我现在想在其中读取一些 POSTed JSON。我使用 Postman Chrome 扩展程序进行 POST,而我 POST 的 JSON 只是{"text":"lalala"}. 我尝试使用以下方法读取 JSON:

@app.route('/api/add_message/<uuid>', methods=['GET', 'POST'])
def add_message(uuid):
    content = request.json
    print content
    return uuid

On the browser it correctly returns the UUID I put in the GET, but on the console, it just prints out None(where I expect it to print out the {"text":"lalala"}. Does anybody know how I can get the posted JSON from within the Flask method?

在浏览器上,它正确返回了我放在 GET 中的 UUID,但在控制台上,它只是打印出来None(我希望它打印出{"text":"lalala"}. 有谁知道我如何从 Flask 方法中获取发布的 JSON?

采纳答案by Martijn Pieters

First of all, the .jsonattribute is a property that delegates to the request.get_json()method, which documents why you see Nonehere.

首先,.json属性是一个委托给request.get_json()方法的属性,它记录了您None在此处看到的原因。

You need to set the request content type to application/jsonfor the .jsonproperty and .get_json()method (with no arguments) to work as either will produce Noneotherwise. See the Flask Requestdocumentation:

您需要将请求内容类型设置application/json.json属性和.get_json()方法(不带参数)才能工作,None否则将产生其他结果。请参阅烧瓶Request文档

This will contain the parsed JSON data if the mimetype indicates JSON (application/json, see is_json()), otherwise it will be None.

如果 mimetype 指示 JSON(application/json,请参阅is_json()),这将包含解析的 JSON 数据,否则它将是None.

You can tell request.get_json()to skip the content type requirement by passing it the force=Truekeyword argument.

您可以request.get_json()通过将force=True关键字参数传递给内容类型要求来告诉它跳过内容类型要求。

Note that if an exceptionis raised at this point (possibly resulting in a 400 Bad Request response), your JSON datais invalid. It is in some way malformed; you may want to check it with a JSON validator.

请注意,如果此时引发异常(可能导致 400 Bad Request 响应),则您的 JSON数据无效。它在某种程度上是畸形的;您可能想使用 JSON 验证器检查它。

回答by radtek

This is the way I would do it and it should be

这是我会做的方式,它应该是

@app.route('/api/add_message/<uuid>', methods=['GET', 'POST'])
def add_message(uuid):
    content = request.get_json(silent=True)
    # print(content) # Do your processing
    return uuid

With silent=Trueset, the get_jsonfunction will fail silently when trying to retrieve the json body. By default this is set to False. If you are always expecting a json body (not optionally), leave it as silent=False.

随着silent=True集,该get_json功能将尝试检索JSON的身体的时候默默的失败。默认情况下,这设置为False。如果您总是期待 json 正文(不是可选的),请将其保留为silent=False.

Setting force=Truewill ignore the request.headers.get('Content-Type') == 'application/json'check that flask does for you. By default this is also set to False.

设置force=True将忽略request.headers.get('Content-Type') == 'application/json'烧瓶为您所做的 检查。默认情况下,这也设置为False

See flask documentation.

请参阅烧瓶文档

I would strongly recommend leaving force=Falseand make the client send the Content-Typeheader to make it more explicit.

我强烈建议离开force=False并让客户端发送Content-Type标头以使其更加明确。

Hope this helps!

希望这可以帮助!

回答by Luke

For reference, here's complete code for how to send json from a Python client:

作为参考,这里是如何从 Python 客户端发送 json 的完整代码:

import requests
res = requests.post('http://localhost:5000/api/add_message/1234', json={"mytext":"lalala"})
if res.ok:
    print res.json()

The "json=" input will automatically set the content-type, as discussed here: Post JSON using Python Requests

“json=”输入将自动设置内容类型,如下所述:使用 Python 请求发布 JSON

And the above client will work with this server-side code:

上面的客户端将使用此服务器端代码:

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

@app.route('/api/add_message/<uuid>', methods=['GET', 'POST'])
def add_message(uuid):
    content = request.json
    print content['mytext']
    return jsonify({"uuid":uuid})

if __name__ == '__main__':
    app.run(host= '0.0.0.0',debug=True)

回答by trojek

Assuming you've posted valid JSON with the application/jsoncontent type, request.jsonwill have the parsed JSON data.

假设您已发布具有application/json内容类型的有效 JSON ,request.json将具有解析的 JSON 数据。

from flask import Flask, request, jsonify

app = Flask(__name__)


@app.route('/echo', methods=['POST'])
def hello():
   return jsonify(request.json)

回答by ?mer Taban

To give another approach.

给出另一种方法。

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

@app.route('/service', methods=['POST'])
def service():
    data = json.loads(request.data)
    text = data.get("text",None)
    if text is None:
        return jsonify({"message":"text not found"})
    else:
        return jsonify(data)

if __name__ == '__main__':
    app.run(host= '0.0.0.0',debug=True)

回答by RAJAHMAD MULANI

Assuming that you have posted valid JSON,

假设您已发布有效的 JSON,

@app.route('/api/add_message/<uuid>', methods=['GET', 'POST'])
def add_message(uuid):
    content = request.json
    print content['uuid']
    # Return data as JSON
    return jsonify(content)

回答by Arcyno

For all those whose issue was from the ajax call, here is a full example :

对于所有问题来自 ajax 调用的人,这里有一个完整的例子:

Ajax call : the key here is to use a dictand then JSON.stringify

Ajax 调用:这里的关键是使用 adict然后JSON.stringify

    var dict = {username : "username" , password:"password"};

    $.ajax({
        type: "POST", 
        url: "http://127.0.0.1:5000/", //localhost Flask
        data : JSON.stringify(dict),
        contentType: "application/json",
    });

And on server side :

在服务器端:

from flask import Flask
from flask import request
import json

app = Flask(__name__)

@app.route("/",  methods = ['POST'])
def hello():
    print(request.get_json())
    return json.dumps({'success':True}), 200, {'ContentType':'application/json'} 

if __name__ == "__main__":
    app.run()

回答by Dip

Try to use force parameter...

尝试使用 force 参数...

request.get_json(force = True)

request.get_json(force = True)