如何从jquery ajax发送POST请求到烧瓶视图?

时间:2017-10-24 18:23:46

标签: jquery python json ajax flask

希望你有一个美好的一天:D 所以让我先解释一下我要做的事情:我有一个html页面(index.html)和一个视图(/ index)index.html页面中包含一个表单,在提交时将使用jquery ajax发送一个json对象到/ index视图 这是非常简单直接的index.html的代码:

<body>
<form action="/" method='post'>
    <button id='submit'>submit</button>
</form>

<script src="../static/jquery.min.js"></script>
<script>
    function saveMenu() {
        localStorage.setItem("shoppingMenu", JSON.stringify(
            [{"name":"*Kabab Combo Plate","price":10.99,"count":4},
            {"name":"Mixed Grill(Lamb, Chicken, Kefta)","price":14.99,"count":4}]
            ));
    };

    saveMenu();

    function loadMenu() {
        menu = JSON.parse(localStorage.getItem("shoppingMenu"));
        return menu;
    };
</script>
<script>
    $(document).ready(function() {
        var menu = JSON.stringify(loadMenu());
        $('#submit').click(function(){
            $.ajax({
                data: menu,
                dataType: 'json',
                type: 'POST',
                contentType: 'application/json; charset=utf-8',
                url: '{{ url_for("index") }}',
                success: function(m){
                        console.log(m);
                },
                error: function(m){
                    console.log(m);
                }
            });
        });
    });
</script>
</body>

这里是/ index视图的代码,注意我添加了print语句,这是出于调试目的,你会在短时间内看到我的意思:

@app.route('/', methods=['POST', 'GET'])
def index():
    if request.method == 'POST':
        data = request.json
        print('header: ', request.headers.get('Content-Type'))
        print('data type: ', type(data))
        print('data = ', data)
        for i in data:
            print(i)
        return 'success'
    return render_template('index.html')

现在这是执行上一个代码时发生的事情:

* Debugger is active!
* Debugger PIN: 143-889-961
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [24/Oct/2017 21:12:20] "GET / HTTP/1.1" 200 -
header:  application/json; charset=UTF-8
data type:  <class 'list'>
data =  [{'name': '*Kabab Combo Plate', 'count': 4, 'price': 10.99}, {'name': 'Mixed Grill(Lamb, Chicken, Kefta)', 'count': 4, 'price': 14.99}]
{'name': '*Kabab Combo Plate', 'count': 4, 'price': 10.99}
{'name': 'Mixed Grill(Lamb, Chicken, Kefta)', 'count': 4, 'price': 14.99}
127.0.0.1 - - [24/Oct/2017 21:12:24] "POST / HTTP/1.1" 200 -
header:  application/x-www-form-urlencoded
data type:  <class 'NoneType'>
data =  None
127.0.0.1 - - [24/Oct/2017 21:12:24] "POST / HTTP/1.1" 500 -
Traceback (most recent call last):
  File "C:\Users\Orbit\flaskname\lib\site-packages\flask\app.py", line 1997, in __call__
    return self.wsgi_app(environ, start_response)
  File "C:\Users\Orbit\flaskname\lib\site-packages\flask\app.py", line 1985, in wsgi_app
    response = self.handle_exception(e)
  File "C:\Users\Orbit\flaskname\lib\site-packages\flask\app.py", line 1540, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\Orbit\flaskname\lib\site-packages\flask\_compat.py", line 33, in reraise
    raise value
  File "C:\Users\Orbit\flaskname\lib\site-packages\flask\app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\Orbit\flaskname\lib\site-packages\flask\app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\Users\Orbit\flaskname\lib\site-packages\flask\app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\Orbit\flaskname\lib\site-packages\flask\_compat.py", line 33, in reraise
    raise value
  File "C:\Users\Orbit\flaskname\lib\site-packages\flask\app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\Users\Orbit\flaskname\lib\site-packages\flask\app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:\Users\Orbit\flaskname\app\hello.py", line 25, in index
    for i in data:
TypeError: 'NoneType' object is not iterable
127.0.0.1 - - [24/Oct/2017 21:12:24] "GET /?__debugger__=yes&cmd=resource&f=style.css HTTP/1.1" 200 -
127.0.0.1 - - [24/Oct/2017 21:12:24] "GET /?__debugger__=yes&cmd=resource&f=jquery.js HTTP/1.1" 200 -
127.0.0.1 - - [24/Oct/2017 21:12:24] "GET /?__debugger__=yes&cmd=resource&f=debugger.js HTTP/1.1" 200 -
127.0.0.1 - - [24/Oct/2017 21:12:24] "GET /?__debugger__=yes&cmd=resource&f=ubuntu.ttf HTTP/1.1" 200 -
127.0.0.1 - - [24/Oct/2017 21:12:24] "GET /?__debugger__=yes&cmd=resource&f=console.png HTTP/1.1" 200 -

通过查看print语句输出,并在错误显示之前注意request.json正常工作并返回我们期望的数据,但然后显示127.0.0.1 - - [24/Oct/2017 21:12:24] "POST / HTTP/1.1" 200 -然后它看起来像视图函数正在重新运行,然后print语句输出none作为数据变量的值...有谁知道为什么会发生这种模式?以及如何解决它?

2 个答案:

答案 0 :(得分:1)

问题是,默认情况下,表单中的提交事件(在这种情况下,当您单击提交按钮时发生)将重定向到表单的action,因此,您实际上是在做两个请求(ajax和默认值)。

要防止这种情况,请在点击处理程序中触发event.preventDefault(并将event添加到参数中)。

.click(function(event) {
  // ...
  event.preventDefault()
}

您还需要从烧瓶视图中返回json响应,如下所示:

from flask import jsonify

# ...

  return jsonify('success')

答案 1 :(得分:0)

您可以通过删除html模板中的表单来修复当前模式:

<button id='submit'>submit</button>

如果需要,让按钮单独或将其放在另一个部分中,但表单似乎是并行请求。我会尝试将一些文档链接到更好地解释它。