【问题标题】:Got Failed to decode JSON object when calling a POST request in flask python在烧瓶 python 中调用 POST 请求时无法解码 JSON 对象
【发布时间】:2016-09-28 03:40:39
【问题描述】:

我在 python 中使用flask 编写了一个简单的 REST-ful Web 服务器,遵循此tutorial 中的步骤;但我在调用POST 请求时遇到问题。代码是:

@app.route('/todo/api/v1.0/tasks', methods=['POST'])
def create_task():
    if not request.json or not 'title' in request.json:
        abort(400)
    task = {
        'id': tasks[-1]['id'] + 1,
        'title': request.json['title'],
        'description': request.json.get('description', ""),
        'done': False
    }
    tasks.append(task)
    return jsonify({'task': task}), 201

我使用curl作为上述页面中的示例发送POST请求:

curl -i -H "Content-Type: application/json" -X POST -d '{"title":"Read a book"}' http://127.0.0.1:5000/todo/api/v1.0/tasks

但我得到这个错误的回应:

HTTP/1.0 400 BAD REQUEST
Content-Type: text/html
Content-Length: 187
Server: Werkzeug/0.11.10 Python/2.7.9
Date: Mon, 30 May 2016 09:05:52 GMT

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>400 Bad Request</title>
<h1>Bad Request</h1>
<p>Failed to decode JSON object: Expecting value: line 1 column 1 (char 0)</p>

我尝试调试,发现在get_json 方法中,传递的参数已转换为'\\'{title:Read a book}\\'',因为datarequest_charsetNone;但我不知道解决方案。有什么帮助吗?

编辑 1:

我已经尝试过@domoarrigato 的回答并实现了create_task 方法,如下所示:

@app.route('/todo/api/v1.0/tasks', methods=['POST'])
def create_task():
    try:
        blob = request.get_json(force=True)
    except:
        abort(400)
    if not 'title' in blob:
        abort(400)
    task = {
        'id': tasks[-1]['id'] + 1,
        'title': blob['title'],
        'description': blob.get('description', ""),
        'done': False
    }
    tasks.append(task)
    return jsonify({'task': task}), 201

但这次我通过curl调用POST后得到以下错误:

HTTP/1.0 400 BAD REQUEST
Content-Type: text/html
Content-Length: 192
Server: Werkzeug/0.11.10 Python/2.7.9
Date: Mon, 30 May 2016 10:56:47 GMT

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>400 Bad Request</title>
<h1>Bad Request</h1>
<p>The browser (or proxy) sent a request that this server could not understand.</p>

编辑 2:

为了澄清,我应该提到我正在使用 Python 2.7 版和最新版本的 Flask 开发 64 位版本的 Microsoft Windows 7。

【问题讨论】:

    标签: python json flask webserver flask-restful


    【解决方案1】:

    这适用于 Windows 7 64:

    curl -i -H "Content-Type: application/json" -X POST -d "{\"title\":\"Read a book\"}" http://localhost:5000/todo/api/v1.0/tasks
    

    反斜杠和双引号。

    【讨论】:

    • 为我工作!使用 Windows 10 x64。谢谢!
    • 谢谢@dmitriy-bogdanov 这在 Windows 10 - 64 位版本中对我有用...
    • 使用powershell你需要使用`来转义双引号
    【解决方案2】:

    如果您使用的是 windows,您的请求中的 json 字符串应如下所示:

    "{\"title\":\"Read a boo\"}"
    

    我遇到了同样的问题,但它有所帮助。

    【讨论】:

    • 这不是一个有效的答案!
    【解决方案3】:

    我设法使用 Anaconda cmd 窗口 python3 使其工作,在整个表达式周围使用反斜杠和双引号! 作品:

    curl "localhost:5000/txion" -H "Content-Type: application/json" -d "{\"from\": \"akjflw\" ,\"to\" : \"fjlakdj\", \"amount\": 4}"
    

    不起作用:

    curl "localhost:5000/txion" -H "Content-Type: application/json" -d '{\"from\": \"akjflw\" ,\"`to\" : \"fjlakdj\", \"amount\": 4}'
    

    【讨论】:

      【解决方案4】:

      不要使用request.json 属性,而是尝试使用request.get_json(force=True) 我会重写它:

      @app.route('/todo/api/v1.0/tasks', methods=['POST'])
      def create_task():
          try:
              blob = request.get_json(force=True)
          except:
              abort(400)
          if not 'title' in blob:
              abort(400)
          task = {
              'id': tasks[-1]['id'] + 1,
              'title': blob['title'],
              'description': blob.get('description', ""),
              'done': False
          }
          tasks.append(task)
          return jsonify({'task': task})
      

      【讨论】:

      • 更新了我的答案-删除了返回语句中的, 201-我认为您只需要返回序列化的json。
      【解决方案5】:

      只需在 JSON 字符串周围放置 " 而不是 ',并在 JSON 字符串中的任何 " 之前放置 \。

      【讨论】:

        【解决方案6】:

        如果你使用 powershell 来使用 CURL,你需要使用 curl.exe 专门(不是curl)添加'dumb parsing'标签--%

        然后你所要做的就是双引号它并在 JSON 中转义双引号。外部单引号似乎不起作用。

        "{\"title\":\"Read a book\"}"
        

        【讨论】:

          【解决方案7】:
          from flask import Flask, request, abort, jsonify
          
          app = Flask(__name__)
          tasks = [{'id': 0}]
          
          @app.route('/todo/api/v1.0/tasks', methods=['POST'])
          def create_task():
              if not request.json or 'title' not in request.json:
                  abort(400)
              task = {
                  'id': tasks[-1]['id'] + 1,
                  'title': request.json['title'],
                  'description': request.json.get('description', ""),
                  'done': False
              }
              tasks.append(task)
              response = {"task": task}
              return jsonify(response), 201
          
          if __name__ == '__main__':
              app.run(host='0.0.0.0', port=5000, debug=True)
          

          卷曲:

          curl -i -H "Content-Type: application/json" -X POST -d '{"title":"Read a book"}' http://127.0.0.1:5000/todo/api/v1.0/tasks
          

          操作:

          {
            "task": {
              "description": "", 
              "done": false, 
              "id": 1, 
              "title": "Read a book"
            }
          }
          

          【讨论】:

          • 你的解决方案和我的完全一样!
          • 是的,就是这样!我无法重现错误!!
          • @Amit Karnik 当您在 Windows 中运行时会出现此错误,因为无法理解 meta char ` " ` 它必须使用的目的。所以使用 ` \" ` 而不是 ` " ` 将完美运行。
          • 每个人都知道...有什么不同吗??
          猜你喜欢
          • 1970-01-01
          • 2022-07-11
          • 2016-04-21
          • 1970-01-01
          • 2012-04-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-07-23
          相关资源
          最近更新 更多