代码之家  ›  专栏  ›  技术社区  ›  Espoir Murhabazi

ajax请求由于错误的json导致flask出现400错误

  •  0
  • Espoir Murhabazi  · 技术社区  · 7 年前

    这是我的代码!!对于HTML和js:

    <!DOCTYPE html>
    <html >
        <head>
            <meta charset="UTF-8">
            <title>Check your Grades</title>
            <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
            <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
            <script src="{{ url_for('static', filename='js/bootstrap3-typeahead.min.js')}}"></script>
            <script type="text/javascript" src="{{ url_for('static', filename='js/index.js')}}"></script>
            <link rel="stylesheet" href="{{url_for('static', filename='css/style.css')}}">
        </head>
        <body>
            <link href='https://fonts.googleapis.com/css?family=Lato' rel='stylesheet' type='text/css'>
            <form id="predict-form" method="POST">
                <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
                <p> welcome to grade predictor app,</p>
                <p>Dear Plateform,</p>
                <p>je viens
                    <label for="SCHOOL_RIGHT"> de </label>
                    <input class="typeahead"  type="text" name="SCHOOL_RIGHT" id="SCHOOL_RIGHT" minlength="3" placeholder="(votre ecole de provenance)" data-provide="typeahead" autocomplete="off" required> et </p>
                <p>dans
                    <label for="OPTION_RIGHT">l'option</label>
                    <input class="typeahead"
                           name="OPTION_RIGHT" id="OPTION_RIGHT" data-provide="typeahead" placeholder="(choisissez votre option )" required>
                </p>
                <p>j'ai obtenu
                    <label for="DIPPERC"></label>
                    <input  type="number" name="DIPPERC" min="50" max="100" id="DIPPERC" placeholder="(Poucentage du
                                                                                                      diplome )" required> % à l\'exetat
                </p>
                <p>
                    <button type="submit">
                        <svg version="1.1" class="send-icn" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="100px" height="36px" viewBox="0 0 100 36" enable-background="new 0 0 100 36" xml:space="preserve">
                            <path d="M100,0L100,0 M23.8,7.1L100,0L40.9,36l-4.7-7.5L22,34.8l-4-11L0,30.5L16.4,8.7l5.4,15L23,7L23.8,7.1z M16.8,20.4l-1.5-4.3
                                     l-5.1,6.7L16.8,20.4z M34.4,25.4l-8.1-13.1L25,29.6L34.4,25.4z M35.2,13.2l8.1,13.1L70,9.9L35.2,13.2z" />
                        </svg>
                        <small>send</small>
                    </button>
                </p>
            </form>
            <script >
                var csrf_token = "{{ csrf_token() }}";
                // this will send a token each time before a session started
                $.ajaxSetup({
                    beforeSend: function(xhr, settings) {
                        if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
                            xhr.setRequestHeader("X-CSRFToken", csrf_token);
                        }
                    }
    
                });
                //submit form data
                $("form#predict-form").submit(function(e){
                    console.log("form submitted")
                    e.preventDefault();
                    var data = {
                    }
    
                    var Form = this;
                    //Gathering the Data
                    //and removing undefined keys(buttons)
                    $.each(this.elements, function(i, v){
                        var input = $(v);
                        data[input.attr("name")] = input.val();
                        delete data["csrf_token"];
                        delete data["undefined"];
                    });
    
                    data["DIPPERC"] = data["DIPPERC"]/100.0
                    //Form Validation goes here....
                    //Save Form Data........
                    $.ajax({
                        cache: false,
                        url : "{{url_for('predict')}}",
                        type: "POST",
                        contentType: "application/json; charset=utf-8",
                        dataType: "json",
                        data : JSON.stringify(data),
                        success : function(callback){
                            //Where $(this) => context == FORM
                            console.log("data sucessfuly submitted")
                            console.log(JSON.parse(callback));
                        }
                        ,
                        error : function(){
                            console.log('erroor')
                        }
                    });
    
                })
            </script>
        </body>
    </html>
    

    我已经检查了所有相关的问题,但什么都没有。

    但我的研究表明,400误差可能由以下原因引起:

    • Csrf令牌缺失 this
    • ContentType和applicationType未设置(已设置但未设置)
    • 已经查到官方烧瓶文件,他们说:(来自)
    • 我正在发送正确的json数据
    • 这是我的简单视图函数
    @predictions.route('/predictions/predict/', methods=['GET', 'POST'])
    def predict():
        if request.method == 'POST':
            print "hello----------------------"
            print request.method
            print request.get_json(force=True)
            return "done "
    

    def test_1_can_connect_post(self):
        """
    Test API can create a  (POST request)
    """
        new_student = {
            'DIPPERC':0.60, 'SCHOOL_RIGHT':'itfm/bukavu', 'OPTION_RIGHT':'elec indust'
        }
        res = self.client().post('predictions/predict/', data=json.dumps(new_student), content_type='application/json')
        self.assertEqual(res.status_code, 201)
    

    Ps:我确信我遗漏了一点,但不知道是什么,可能是ajax异步出错了。。。。。

    2 回复  |  直到 4 年前
        1
  •  0
  •   Laurent LAPORTE    7 年前

    您不需要将数据转换为字符串:删除 JSON.stringify

    $.ajax({
        cache: false,
        url : "{{url_for('predict')}}",
        type: "POST",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        data : data,
        success : function(callback){
            //Where $(this) => context == FORM
                  console.log("data sucessfuly submitted")
                  console.log(JSON.parse(callback));
        },
        error : function(){
            console.log('erroor')
        }
    });
    

    具有 JSON。字符串化

        2
  •  0
  •   Espoir Murhabazi    7 年前

    我做两件事:

    1. 从现在起,为了我未来的网络开发 因此,对于我的代码,我决定使用纯javascript,下面是我用来发送请求的代码:

      var csrf_token = "{{ csrf_token() }}";
      // this will send a token each time before a session started
      var form = document.getElementById("predict-form");
      
      form.onsubmit = function (e) {
      // stop the regular form submission
      e.preventDefault();
      
      // collect the form data while iterating over the inputs
      var formEntries = new FormData(form).entries();
      var data = Object.assign(...Array.from(formEntries, ([x,y]) => ({[x]:y})));
      delete data["csrf_token"];
      data["DIPPERC"] = data["DIPPERC"]/100.0
      
      console.log(data);
      // construct an HTTP request
      var xhr = new XMLHttpRequest();
      xhr.open(form.method, form.action, true);
      xhr.setRequestHeader("X-CSRFToken", csrf_token);
      xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
      // send the collected data as JSON
      xhr.send(JSON.stringify(data));
      
      xhr.onloadend = function () {
      console.log('blallala ')
      };
      };
      

      这是javascript部分,我确信我正在向我的服务器发送好的json对象

    2. here 在flask官方文档中,找到了flask请求对象的这两行属性

    :

    数据 以字符串形式包含传入请求数据,以防mimetype烧瓶无法处理

    并将我的后端代码更改为:

    @predictions.route('/predictions/predict/', methods=['GET', 'POST'])
    def predict():
        """
    
        the main methode use to predict
    
        """
        if request.method == 'POST':
            print "hello----------------------"
            print request.is_json
            print request.data
            print '-----------------------------------------'
        return "done "
    

    瞧!!!!以python dict.的形式获取200状态代码和数据。