2016-05-30 86 views
1

我已经用python编写了一个简单的REST-ful web服务器,其中flask遵循了此tutorial中的步骤;但我有一个问题叫POST请求。该代码是:无法在烧瓶python中调用POST请求时解码JSON对象

@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。

回答

0

除了使用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}) 
+0

请查看我对该问题的更新。 –

+0

更新了我的答案 - 在return语句中删除了',201' - 我想你只需要返回序列化的json。 – domoarrigato

+0

不幸的是,它没有奏效。 –

-1
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 

OP:

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

您的解决方案与我的完全相同! –

+0

是的,这是什么!我无法重现错误! –

0

如果您使用的是windows,您的请求中的json字符串应该如下所示:“{\”title \“:\”Read a boo \“}”。我有同样的问题,它有帮助。

+2

这不是一个有效的答案! –