【问题标题】:Flask Ajax post returns TypeError: 'NoneType' object is not iterable for form data [duplicate]Flask Ajax post返回TypeError:'NoneType'对象不可迭代表单数据[重复]
【发布时间】:2019-05-30 14:28:31
【问题描述】:

我已经看到了多个关于如何使用 wtf-forms 在烧瓶中实现 ajax post 方法的问题,并且我已经阅读了文档。我以this post 为例,但收到 TypeError: 'NoneType' object is not iterable。我已经验证了不使用 ajax 的表单数据,一切正常。我不确定为什么它不适用于 ajax 请求。

我的表格:

class PathsForm(FlaskForm):
    name = StringField('Name', validators = [DataRequired()])
    paths = SelectField('Path')
    cbt_id = HiddenField('CBT ID', validators = [DataRequired()])

我的模板:

{% extends "base.html" %}

{% block content %}
    <h1>Edit {{ cbt.name }} </h1>
    <form action="" method="post">
        {{ form.hidden_tag() }}
    <table>
        <tr>
            <th>{{ form.name.label }}</th>
            <th>{{ form.paths.label }}</th>
        <tr>
            <td>{{ form.name(size=32) }}</td>
            <td>{{ form.paths() }}</td>
        </tr>
    </table>
    {{ form.cbt_id() }}
    <input type = "submit" value = "Add Path"/>
    </form>

    <script type="text/javascript">

    $(document).ready(function() {
        $('form').submit(function (e) {
            var url = "{{ url_for('process_cbt') }}"; // send the form data here.
            $.ajax({
                type: "POST",
                url: url,
                dataType: "json",
                data: $('form').serialize(),// serializes the form's elements.
                success: function (data) {
                    console.log(data)  // display the returned data in the console.
                }
            });
            e.preventDefault(); // block the traditional submission of the form.
        });
        // Inject our CSRF token into our AJAX request.
        $.ajaxSetup({
            beforeSend: function(xhr, settings) {
                if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
                    xhr.setRequestHeader("X-CSRFToken", "{{ form.csrf_token._value() }}")
                }
            }
        })
    });
    </script>
{% endblock %}

我的烧瓶路线:

@app.route('/process_cbt', methods = ['POST'])
@login_required
def process_cbt():
    form = PathsForm()
    if form.validate_on_submit():
        return jsonify(data={'message':'Success'})
    return jsonify(data={'message': 'Failure'})

看起来 csrf 令牌已正确实施,我已按照 the documentation 设置 CSRF 保护。

谁能告诉我为什么我会收到一个空表格?

谢谢

【问题讨论】:

    标签: ajax forms flask csrf flask-wtforms


    【解决方案1】:

    我认为您需要在包含 CSRF 令牌的 AJAX 请求中放入标头,就像这样

                          headers: {
    
                            "X-CSRFToken": "{{csrf_token()}}"
                          }
    

    【讨论】:

    • 感谢 Avian,但我认为这就是 ajaxSetup 在模板底部所做的。不过我会试一试的!
    • 现在给我一个错误的请求 无法解码 JSON 对象:期望值:第 1 行第 1 列(字符 0)
    • 糟糕!忘记 application/json 内容类型,只需先尝试使用 CSRF 令牌。我已经编辑了我的原始帖子 - 尝试这样做。
    • 不,现在回到TypeError: 'NoneType' object is not iterable
    • 嗯,老实说,我不确定。我自己从不使用 AJAX,所以我没有猜测。
    【解决方案2】:

    经过比我想承认的更多的谷歌搜索后,我看到this answer 并意识到我的问题不是基于 ajax,而是表单验证的问题。我动态地输入了我的选择,因此当它尝试验证时,它没有任何选择可以验证。我将视图更改为以下内容,一切顺利。

    def process_cbt():
        form = PathsForm()
        choice = request.form.get('paths')
        form.paths.choices = [(choice,choice)]
        if form.validate_on_submit():
            return jsonify(data={'message':'success'})
        return jsonify(data={'message': 'Failure'})
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-25
      • 1970-01-01
      • 2021-12-05
      • 2017-08-29
      • 2016-08-30
      相关资源
      最近更新 更多