Angularjs + Flask-wtf: Bad request 400

426 views Asked by At

I got a very strange issue with wtf-forms where I send a request using the angularjs $http-module. Upon initializing the WTForm I recieve a Bad request: 400 error. For testing purposes I disabled csrf protection. I have seriously no idea where to look for the problem. The following is the minimal failing:

Angularjs service sending the request:

var data = new FormData();
data.append('surname', _gifter.surname);
data.append('lastname', _gifter.lastname);
data.append('email', _gifter.email);
data.append('email_confirm', _gifter.email_confirm);
data.append('prize', gift.prize);

$http.post('ajax/claim/' + DataProvider.gift.id + '/', data)

Flask route:

@app.route('/ajax/claim/<int:gift_id>/', methods = ['POST'])
def claim_gift(gift_id):
    print("request:" + request.data)
    claim_form = ClaimGiftForm(csrf_enabled=False)
    return 'success'

WTForm:

class ClaimGiftForm(Form):
    surname = TextField(
        validators=[validators.Required()])
    lastname = TextField(
        validators=[validators.Required()])
    email = EmailField(
        validators = [
            validators.email(),
            validators.Required()])
    email_confirm = EmailField(
        validators = [
            validators.Required(),
            validators.EqualTo()])
    prize = IntegerField()

When I print the request (see in 'Flask route') the data seems to be ok - everything is transmitted correctly. But upon initializing the form I get the aforementioned error.

Edit1: I just found out, that for some reason the request.form MultiDict is empty, allthough request.data contains the expected data. However I have no idea why this is the case.

Edit2: pprint(request.data) gives:

-----------------------------109386632915471364402090498247\r\nContent-Disposition: form-data; name="surname"\r\n\r\ntheName\r\n
-----------------------------109386632915471364402090498247\r\nContent-Disposition: form-data; name="lastname"\r\n\r\ntheLastname\r\n
-----------------------------109386632915471364402090498247\r\nContent-Disposition: form-data; name="email"\r\n\r\[email protected]\r\n
-----------------------------109386632915471364402090498247\r\nContent-Disposition: form-data; name="email_confirm"\r\n\r\[email protected]\r\n
-----------------------------109386632915471364402090498247\r\nContent-Disposition: form-data; name="prize"\r\n\r\n12\r\n
-----------------------------109386632915471364402090498247--\r\n'
2

There are 2 answers

2
Celeo On

Your JavaScript has email_confirmed but the form's field is email_confirm.

0
theCalcaholic On

It was the header of the ajax request. I needed to add a header-config object:

{
    withCredentials: true,
    headers: {'Content-Type': undefined},
    transformRequest: angular.identity
}

The whole request now looks like this:

$http.post('ajax/claim/' + DataProvider.gifts[index].id + '/', data, {
    withCredentials: true,
    headers: {'Content-Type': undefined},
    transformRequest: angular.identity
).success(...);

I consider this question as closed.