Flask request.get_json() 返回字符串而不是 json

Bak*_*aki 8 python json flask

使用Flask 1.0.2on WindowsPython 3.6 64bit 首先我通过jquery ajax调用发送数据,这在 JS 端是有效的json

var myData = '{ "id": "' +clickedID +'" }'
$.ajax({
    type: "POST", // HTTP method POST or GET
    contentType: 'application/json; charset=utf-8', //content type
    url: $SCRIPT_ROOT + '/colors/delete', //Where to make Ajax calls
    dataType:'json', // Data type, HTML, json etc.
    processData: false,
    data:JSON.stringify(myData), 
});
Run Code Online (Sandbox Code Playgroud)

在烧瓶中,我捕获了 POST 请求并尝试解析它:

if request.method == "POST":
    print("got request method POST")
if request.is_json:
    print("is json")
    data_json = request.get_json(force=True)
    data_req = request.data
    print("{} is {}".format(data_req, type(data_req)))
    print("{} is {}".format(data_json, type(data_json)))
    data_json2 = json.loads(request.get_json(silent=True, force=True))
    print("{} is {}".format(data_json2, type(data_json2)))
    print (request.json.keys())
Run Code Online (Sandbox Code Playgroud)

结果:

got request: POST
is json
b'"{ \\"id\\": \\"1\\" }"' is <class 'bytes'>
{ "id": "1" } is <class 'str'>
{'id': '1'} is <class 'dict'>
print (request.json.keys())
AttributeError: 'str' object has no attribute 'keys'
Run Code Online (Sandbox Code Playgroud)

Wil*_*ing 6

JSON.stringify()接受一个 Javascript 对象并将其转换为 JSON 字符串。您不是向它传递一个对象,而是向它传递一个字符串,然后再次将其转换为 JSON。

由于请求数据包含双重编码的 JSON,因此该request.json属性会返回一个字符串而不是字典。

要修复,请更改:

var myData = '{ "id": "' +clickedID +'" }'
Run Code Online (Sandbox Code Playgroud)

到:

var myData = { id: clickedID }
Run Code Online (Sandbox Code Playgroud)


Ste*_*eve 3

总而言之,您将对象序列化为 JSON(实际上是一个字符串),使用 JSON 数据类型对其进行 POST,然后对其进行反序列化以取回该对象。有些对象很容易使用现成的功能进行序列化和反序列化)。请参阅下面基于您修改的代码的示例(忽略 CORS,因为这是由于我的测试环境设置造成的)。

import logging, json
from flask import Flask, request, jsonify
from flask_cors import CORS
app = Flask(__name__)
CORS(app)

@app.route("/api",methods=['POST'])
def hello():
    logging.info('hello')
    if request.method == "POST":
        print("got request method POST")
    if request.is_json:
        print("is json")
        data = request.get_json()
        print("type of data {}".format(type(data))) # type dict
        print("data as string {}".format(json.dumps(data)))
        print ("keys {}".format(json.dumps(data.keys())))
    return jsonify(message='success')

if __name__ == "__main__":
    app.run()

<html>
    <style>
    </style>
    <button onClick="_ajax()">POST</button>
    <script src="jquery.js"></script>
    <script>
        const url_path = "http://localhost:5000/api";
        function _ajax() {
            console.log('_ajax called');
            var xhttp = new XMLHttpRequest();
            var clickedID="testClickedID";
            var myData = {"id": clickedID};
            $.ajax({
                type: "POST", // HTTP method POST or GET
                contentType: 'application/json; charset=utf-8', //content type
                url: url_path, //Where to make Ajax calls
                dataType:'json', // Data type, HTML, json etc.
                processData: false,
                data: JSON.stringify(myData), 
            }).done(
                function(data) {
                    console.log(data);
                }
            );
        }
    </script>
</html>
Run Code Online (Sandbox Code Playgroud)