Flask请求和application/json内容类型

dan*_*rvt 25 python json dictionary flask mime-types

我有一个带有以下视图的烧瓶应用程序:

@menus.route('/', methods=["PUT", "POST"])
def new():
    return jsonify(request.json)
Run Code Online (Sandbox Code Playgroud)

但是,这仅在请求的内容类型设置为时才有效application/json,否则dict request.json为None.

我知道request.data请求体是一个字符串,但我不希望每次客户端忘记设置请求的内容类型时将其解析为dict.

有没有办法假设每个传入请求的内容类型是application/json?我想要的是始终可以访问有效的request.jsondict,即使客户端忘记将应用程序内容类型设置为json.

Mar*_*ers 52

使用request.get_json()并设置forceTrue:

@menus.route('/', methods=["PUT", "POST"])
def new():
    return jsonify(request.get_json(force=True))
Run Code Online (Sandbox Code Playgroud)

从文档:

默认情况下,如果mimetype是,则此函数仅加载json数据,application/json但这可以被force参数覆盖.

参数:

  • force - 如果设置为True,则忽略mimetype.

对于较旧的Flask版本,<0.10,如果您想要宽容并允许使用JSON,您可以自己进行解码:

from flask import json

@menus.route('/', methods=["PUT", "POST"])
def new():
    return jsonify(json.loads(request.data))
Run Code Online (Sandbox Code Playgroud)

  • @MartijnPieters request.data在使用www/form-url-encoded时是一个空字符串,因为它将其解析为表单.从文档:data - 包含传入的请求数据作为字符串,以防它带有Flask无法处理的mimetype. (6认同)
  • @TonyChou:关于Content-Type标头的门控是提前阻止坏客户端的一种方法.如果你使用`force = True`只是因为有些客户可能忘记设置标题,那么你的服务器将不得不做更多的工作(因为现在所有的请求都可以包含JSON,并且花费时间来尝试解码它). (2认同)

jos*_*ama 12

request对象已经有一个方法get_json可以为您提供json,无论内容类型如何,如果您执行它,force=True所以您的代码将类似于以下内容:

@menus.route('/', methods=["PUT", "POST"])
def new():
    return jsonify(request.get_json(force=True))
Run Code Online (Sandbox Code Playgroud)

事实上,烧瓶文档说request.get_json应该使用而不是request.json:http://flask.pocoo.org/docs/api/?highlight = json#flask.Request.json