无法在 Flask 应用程序中通过 AJAX 成功验证 reCAPTCHA

Cannot succesfully validate reCAPTCHA via AJAX in Flask application

我正在制作一个 Flask 应用程序,我正在尝试使用 Google reCAPTCHA 在发送表单之前进行验证。

但是,我经常遇到错误。软件无法识别我按下了 reCAPTCHA 按钮,我不知道为什么。 在我输入 reCAPTCHA 字段之前,一切正常。

完整代码如下:

1) 烧瓶:

from flask import Flask, render_template, request, jsonify
from flask_wtf.csrf import CSRFProtect
from flask_bootstrap import Bootstrap
from flask_wtf import FlaskForm
from wtforms import StringField
from wtforms.validators import InputRequired
from flask_wtf.recaptcha import RecaptchaField


app = Flask(__name__)

app.config['SECRET_KEY'] = 'proba123Jakov'
app.config.update(
    RECAPTCHA_ENABLED = True,
    RECAPTCHA_PUBLIC_KEY = 'mypublickey',
    RECPATCHA_PRIVATE_KEY = 'myprivatekey',
)

csrf = CSRFProtect(app)
Bootstrap(app)

class MailForm(FlaskForm):
    firstname = StringField('Name *', _name='firstname', validators=[InputRequired()], render_kw={"placeholder": "Your name"}, id="firstnameInput")
    lastname = StringField('Surname *', _name='lastname', validators=[InputRequired()], render_kw={"placeholder": "Your surname"}, id="lastnameInput")
    recaptcha = RecaptchaField()

@app.route('/')
def contact():
    form = MailForm()
    return render_template('contactForm.html', form=form)

@app.route('/send', methods=['POST'])
def mailSend():
    global previousEmailMessage
    form = MailForm()

    if form.validate_on_submit():
        return jsonify({'firstname' : request.form.get('firstname'), 'lastname' : request.form.get('lastname')})
    return jsonify({'error' : 'You havent put all data or press recaptcha button'})

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

2) JS:

$(document).ready(function() {

    var csrftoken = $('meta[name=csrf-token]').attr('content');

    $.ajaxSetup({
        beforeSend: function(xhr, settings) {
            if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type)) {
                xhr.setRequestHeader("X-CSRFToken", csrftoken)
            }
        }
    });

    $('#contact-form').on('submit', function(event) { // GET METHOD IS ACTIVATED SOMEHOW

        $.ajax({
            data : {
                firstname : $('#firstnameInput').val(),
                lastname : $('#lastnameInput').val(),
                message : $('#messageInput').val()
            },
            type : 'POST',
            headers: {
                'Cache-Control': 'no-cache, no-store, must-revalidate',
                'Pragma': 'no-cache',
                'Expires': '0'
            },
            url : '/send',
            dataType: "json"
        })
        .done(function(data) {

            if (data.error) {
                $('#successAlert').hide();
                $('#errorAlert').text(data.error).show();
            }
            else {
                $('#successAlert').text("Vaša poruka je uspješno poslana!").show();
                $('#errorAlert').hide();
            }
        });
        event.preventDefault();
    });

});

3) HTML:

{% extends "bootstrap/base.html" %}
{% import "bootstrap/wtf.html" as wtf %}

{% block head %}
    {{ super() }}
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <script src="https://code.jquery.com/jquery-2.2.4.js"></script>
    <script src="{{ url_for('static', filename='ajaxForm.js') }}" type="text/javascript"></script>
    <script src='https://www.google.com/recaptcha/api.js'></script>
{% endblock %}

{% block content %}

    <form id="contact-form">
        {{ wtf.form_field(form.firstname) }}
        {{ wtf.form_field(form.lastname) }}
        {{ wtf.form_field(form.recaptcha) }}
        <input type="submit" class="btn btn-lg btn-primary btn-block" value="SEND">
        <div id="successAlert" class="alert alert-success" role="alert" style="display:none;"></div>
        <div id="errorAlert" class="alert alert-danger" role="alert" style="display:none;"></div>
    </form>
{% endblock %}

这是我填写表格时得到的:

请帮忙。

我设法解决了这个问题。问题是我没有在 AJAX 请求中发送 reCAPTCHA 字段。

我必须更改 AJAX 请求的 data 才能发送 reCAPTCHA 字段。

data : {
        firstname : $('#firstnameInput').val(),
        lastname : $('#lastnameInput').val(),
        recaptcha : grecaptcha.getResponse()
            }

之后需要在Flask中进行不同的验证。如果 recaptcha 比 0 长,则表示已按下 reCAPTCHA 复选框。

if form.is_submitted():
    if request.form.get('recaptcha'):
        return jsonify({'firstname' : request.form.get('firstname')})
    return jsonify({'error' : 'reCAPTCHA button was not pressed'})

现在可以使用了。