【问题标题】:Getting POST parameters on both, form and json format获取表单和 json 格式的 POST 参数
【发布时间】:2015-04-20 16:11:05
【问题描述】:

我的网络服务应该接收以下两种格式的调用:application/x-www-form-urlencodedcontent-type application/json

以下代码适用于表单。但是,它不适用于 json 格式。显然我需要使用request.args.get

有没有办法修改代码,让同一个方法可以接收这两种格式的调用?

@app.route("/api/<projectTitle>/<path:urlSuffix>", methods=['POST'])
def projectTitlePage(projectTitle, urlSuffix):

    apiKey = request.form.get('apikey')
    userId = databaseFunctions.getApiKeyUserId(apiKey)
    userInfo = databaseFunctions.getUserInfo(userId)
    projectId = databaseFunctions.getTitleProjectId(projectTitle)
    projectInfo = databaseFunctions.getProjectInfo(projectId)
    databaseFunctions.addUserHit(userId, projectId)
    databaseFunctions.addProjectHit(userId)

    print request.form.to_dict(flat=False)
    try:
        r = requests.post(projectInfo['secretUrl'], data=request.form.to_dict(flat=False))
    except Exception, e:
        return '/error=Error'

    return r.text

【问题讨论】:

  • 你能添加你的包含以及你的请求对象是如何分配的吗?
  • 您是否尝试过基于 HTTP CONTENT-TYPE 标头的请求处理分支?
  • 嗨@RPhillipCastagna。您能否在答案中扩展您的评论?我认为这可能行得通!

标签: python api post flask http-post


【解决方案1】:

尝试使用Request.get_json()获取JSON;如果失败则会引发异常,之后您可以回退到使用request.form

from flask import request
from werkzeug.exceptions import BadRequest

try:
    data = request.get_json()
    apiKey = data['apikey']
except (TypeError, BadRequest, KeyError):
    apiKey = request.form['apikey']

如果mimetype不是application/jsonrequest.get_json()返回None;尝试使用data['apikey'] 会导致TypeError。 mimetype 正确但 JSON 数据无效会给您一个 BadRequest,所有其他无效的返回值要么导致 KeyError(没有这样的键)或 TypeError(对象不支持按名称索引) .

另一种选择是测试request.mimetype attribute

if request.mimetype == 'application/json':
    data = request.get_json()
    apiKey = data['apiKey']
else:
    apiKey = request.form['apikey']

无论哪种方式,如果没有发布有效的 JSON 数据或表单数据但没有 apikey 条目或发布了不相关的 mimetype,则会引发 BadRequest 异常并向客户端返回 400 响应.

【讨论】:

    【解决方案2】:

    我对 Flask 并不是特别熟悉,但根据他们的文档,您应该能够做类似的事情

    content = request.headers['CONTENT-TYPE']
    
    if content[:16] == 'application/json':
       # Process json
    else:
       # Process as form-encoded
    

    【讨论】:

    • 如果在请求中添加了参数,这将不起作用; Content-Type: application/json; charset=utf-8 是一个完全有效的发送标头。
    • 改为使用 Werkzeug Request 对象 API; mimetype 属性包含不带任何 MIME 参数的 Content-Type 内容。
    • 好了好了!就像我说的,对 Flask 不是特别熟悉
    【解决方案3】:

    无论标题如何,我获取 jsonform-data 的方法就像

    data = request.get_json() or request.form
    key = data.get('key')
    

    【讨论】:

      猜你喜欢
      • 2015-10-04
      • 2011-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-12
      • 1970-01-01
      • 2018-01-25
      • 2011-10-05
      相关资源
      最近更新 更多