Reputation: 1244
Today I was solving how to use recaptcha from flask-WTF 0.14.2 in form which is POST on server via ajax. I wasn't able to find solution how to implement recaptcha with ajax and successfully validate it on server and then send answer back to client. Recaptcha validation was complaining with this error despite I was sending required "response parameter" from client to server:
'recaptcha': ['The response parameter is missing.']
I was not able to find answer anywhere on Stackoverflow so I post here my own working code.
Upvotes: 0
Views: 1043
Reputation: 1244
Here is my Flask code:
from flask_wtf import FlaskForm, RecaptchaField
from wtforms import StringField, TextAreaField
from wtforms.validators import InputRequired, Email, Length, Optional
#Google keys
app.config['RECAPTCHA_PUBLIC_KEY'] = 'my_public_key'
app.config['RECAPTCHA_PRIVATE_KEY'] = 'My_private_key'
# flask-WTF contact us form
class ContactUs(FlaskForm):
name = StringField('name', validators=[InputRequired(), Length(max=50)])
surname = StringField('surname', validators=[Optional(), Length(max=50)])
email = StringField('email', validators=[InputRequired(), Length(max=100), Email(message='Invalid email')])
message = TextAreaField('message', validators = [InputRequired(), Length(max=5000)])
recaptcha = RecaptchaField()
@app.route ("/contact", methods=['GET','POST'])
def contact():
form = ContactUs()
if request.method =='POST':
if form.validate_on_submit():
#do something with validated data
return jsonify(message = 'ok')
else:
#send back form.errors to front-end
return jsonify(message = "error", data = form.errors)
return render_template("contact.html", form = form)
Here is simplified html template:
<label class="control-label">First name*</label>
{{ form.name }}
<label class="control-label">Last name</label>
{{ form.surname }}
<label class="control-label">Email address*</label>
{{ form.email }}
<label class="control-label">Your message*</label>
{{ form.message }}
{{ form.recaptcha }}
<button type="button" class="btn btn-primary" onclick="SendMessage()">Send Message</button>
And finally here is AJAX part:
function SendMessage(){
var url = "{{url_for('contact')}}"
var name = document.getElementById('name').value
var surname = document.getElementById('surname').value
var email = document.getElementById('email').value
var message = document.getElementById('message').value
var formData = new FormData()
formData.append('name', name.value)
formData.append('surname', surname.value)
formData.append('email', email.value)
formData.append('message', message.value)
formData.append('g-recaptcha-response', grecaptcha.getResponse())
//from flask-wtf library I learnt that recaptcha is awaiting 'g-recaptcha-response' in FormData
$.ajax({
type: 'POST',
url: url,
data: formData,
processData: false,
contentType: false,
success: function(response){
grecaptcha.reset() //recaptcha reset
if(response.message == 'ok'){
console.log('got ok')
}
if(response.message == 'error'){
//handle flask-wtf errors here
}},
error: function(response){
grecaptcha.reset()
console.log('got error')
}
})}
I hope it can help somebody who is looking up recaptcha validation with flask-wtf and ajax.
Upvotes: 1