Ajax将表单数据发送到烧瓶后端的错误路由

时间:2018-03-13 11:14:50

标签: python jquery ajax flask wtforms

我正在使用ajax和jquery将表单数据发送到我的后端。该脚本应该读取来自表单的操作URL,并将表单数据发布到与表单中的操作相同的URL的后端(请参阅下面的代码)。然而,当我填写登录表单时,数据似乎会被发送到后端的寄存器方法,当它应该被发送到 log_in 方法。填写并提交注册表单正确地将数据发送到后端的寄存器方法。所以我很困惑为什么在提交登录表单时没有调用log_in方法。

Ajax和Jquery:

<script>

    $(document).ready(function () {

        $('form').submit(function (e) {
            $.ajax({
                type: "POST",
                url: $('form').attr('action'), // url to post to, from the forms action
                data: $('form').serialize(), 

                success: function (data) {
                    console.log(data)  

                }

            })
            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_login.csrf_token._value() }}")
                    xhr.setRequestHeader("X-CSRFToken", "{{ form_register.csrf_token._value() }}")
                }
            }
        })
    });
</script>

以下是登录表单的html:

{% from "_formhelpers.html" import render_field %}

<div style=" border-style: solid; border-width: 5px; border-color: #FAF6EA">
    <form id="log_in_form" action="{{ url_for('users.log_in') }}">
        <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
        <br>
        <label for="formGroupExampleInput">Returning Customer</label>
        <br>
        <div class="form-group">
            {{ render_field(form_login.email, type="email", class="form-control", id="email", placeholder="Email") }}
        </div>
        <div class="form-group">
            {{ render_field(form_login.password, type="password", class="form-control", id="password", placeholder="Password") }}
        </div>
        <button type="submit" class="btn btn-primary light-button" style="color: black">Submit</button>
        <div><br><br><br><br><br><br><br></div>

    </form>
</div>

以下是注册表单的html:

{% from "_formhelpers.html" import render_field %}

<div style=" border-style: solid; border-width: 5px; border-color: #FAF6EA">
    <form id="sign_up_form" action="{{ url_for('users.register') }}">
        <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
        <br>
        <label for="formGroupExampleInput">Sign up to gain access!</label>
        <br>
        <div class="form-row">
            <div class="form-group col-md-6">
                {{ render_field(form_register.first_name, type="text", class="form-control", id="first_name", placeholder="First Name") }}
            </div>
            <div class="form-group col-md-6">
                {{ render_field(form_register.last_name, type="text", class="form-control", id="last_name", placeholder="Last Name") }}
            </div>
        </div>
        <div class="form-group">
            {{ render_field(form_register.email, type="email", class="form-control", id="email", placeholder="Email") }}
        </div>
        <div class="form-group">
            {{ render_field(form_register.password, type="password", class="form-control", id="password", placeholder="Password") }}

        </div>
        <div class="form-group">
            <div class="form-check">
                <input class="form-check-input" type="checkbox" id="gridCheck" name="confirm_age" required>
                <label class="form-check-label" for="gridCheck">
                    I confirm that I am 19 years of age or older.
                </label>
            </div>
        </div>
        <div class="form-group">
            <div class="form-check">
                <input class="form-check-input" type="checkbox" id="gridCheck" name="policy" required>
                <label class="form-check-label" for="gridCheck">
                    I agree to the CanaXpress terms of service and privacy policy.
                </label>
            </div>
        </div>
        <button type="submit" class="btn btn-primary light-button" style="color: black">Submit</button>
    </form>
</div>

最后负责后端的方法:

user_blueprint = Blueprint('users', __name__)


class RegisterUser(FlaskForm):
    first_name = StringField('first_name', validators=[InputRequired()])
    last_name = StringField('last_name', validators=[InputRequired()])
    email = StringField('email', validators=[InputRequired()])
    password = StringField('password', validators=[InputRequired()])


class LogInUser(FlaskForm):
    email = StringField('email', validators=[InputRequired()])
    password = StringField('password', validators=[InputRequired()])


@user_blueprint.route('/log_in', methods=['POST'])
def log_in():
    form = LogInUser(request.form)
    print("Log in method")

    if form.validate_on_submit():
        email = request.form['email']
        password = request.form['password']
        print("log in form validated")

        try:
            if User.is_login_valid(email, password):
                session['email'] = email
                print("User found and logged in")

        except UserErrors.UserError:          # as e:
            return jsonify(data=form.errors)  # return e.message

        return jsonify(data={'message': 'hello {}'.format(form.data.name)})  # form.data

    print("log in not validated")
    return jsonify(data=form.errors)


@user_blueprint.route('/register', methods=['POST'])
def register():
    form = RegisterUser(request.form)
    print("Signed up")
    if form.validate_on_submit():
        print("validated")

        return jsonify(data={'message': 'hello {}'.format(form.data)})  # form.data
    print("not validated")
    return jsonify(data=form.errors)

我为倾销所有这些代码而道歉但不幸的是我无法缩小问题的范围。我的目标是使用相同的脚本异步处理页面上的所有表单,如果你知道更好的方法,请分享,因为这对我同样有用,谢谢!

1 个答案:

答案 0 :(得分:1)

我猜你有两个表格在同一页面上,如果是你在ajax调用中使用的$(&#39;表单&#39;)将返回它找到的第一个表单,尤其是那个被提交。

您可以使用$(this)来定位当前活动元素。

$('form').submit(function (e) {
        $.ajax({
            type: "POST",
            url: $(this).attr('action'), // url to post to, from the forms action
            data: $(this).serialize(), 

            success: function (data) {
                console.log(data)  

            }

        })
        e.preventDefault(); // block the traditional submission of the form.
    });