如何在Flask中获得POST的json?

kra*_*r65 284 python post json flask

我正在尝试使用Flask构建一个简单的API,我现在想要阅读一些POSTed JSON.我使用PostMan Chrome扩展程序发布帖子,而JSON我的帖子很简单{"text":"lalala"}.我尝试使用以下方法读取JSON:

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

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

Mar*_*ers 381

首先,该.json属性已被弃用,您应该使用该request.get_json()方法.

您需要将请求内容类型设置Noneapplication/json要使属性和.json方法起作用; .get_json()否则产生.请参阅Flask None文档:

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

您可以None通过设置来跳过内容类型要求request.get_json().

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

  • @iBug:请求中格式错误的 JSON 不是服务器错误,而是客户端的错误,使其成为 400 类错误。 (3认同)
  • 我认为当此时引发*异常*时,它更有可能导致 500 内部错误响应,不是吗? (2认同)

Luk*_*uke 86

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

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

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

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

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)
Run Code Online (Sandbox Code Playgroud)


rad*_*tek 65

这就是我应该这样做的方式

@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
Run Code Online (Sandbox Code Playgroud)

使用silent=Trueset,get_json在尝试检索json主体时,该函数将无提示失败.默认设置为False.

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

烧瓶文档.

我强烈建议离开False并让客户端发送force=False标题以使其更明确.

希望这可以帮助!

  • 取决于json主体是否可选,所以取决于您的情况 (2认同)
  • 我看不到任何情况下有时发布有效的json而有时发布无效的json的情况。听起来像两个不同的终点 (2认同)

tro*_*jek 19

此解决方案有效:

from flask import Flask, request, jsonify

app = Flask(__name__)


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

  • 要添加到此答案,您可以发送到此端点的请求可以是`response = request.post('http://127.0.0.1:5000/hello',json = {"foo":"bar"})`.在运行之后`response.json()`应该返回`{'foo':'bar'}` (3认同)

Arc*_*yno 15

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

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",
    });
Run Code Online (Sandbox Code Playgroud)

在服务器端:

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()
Run Code Online (Sandbox Code Playgroud)


Dip*_*Dip 6

尝试使用 force 参数...

request.get_json(force = True)


Öme*_*ban 5

给出另一种方法。

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)
Run Code Online (Sandbox Code Playgroud)


Sor*_*ami 5

您可能会注意到request.jsonrequest.get_json()仅当Content-type: application/json已添加到请求的标头中时才起作用。如果您无法更改客户端请求配置,那么您可以像这样将正文作为 json 获取:

data = json.loads(request.data)
Run Code Online (Sandbox Code Playgroud)