Reputation: 1840
Trying to understand what I'm doing wrong here when using JQuery AJAX POST request to send both form data and an attached file to a Flask endpoint.
The basic Flask view that I'm still building looks like this:
@main.route('/videoupload', methods=['GET','POST'])
def videoupload():
if request.method == 'POST':
ajaxpost = request.form['m_data']
print(ajaxpost)
return render_template('videoupload.html')
The JQuery for the form and attached file looks like this:
$("#submit_btn").click(function() {
var proceed = true;
if(proceed) //everything looks good! proceed...
{
//data to be sent to server
var m_data = new FormData();
m_data.append( 'video_title', $('input[name=videoTitle]').val());
m_data.append( 'video_description', $('input[name=videoDescription]').val());
m_data.append( 'video_tags', $('input[name=videoTags]').val());
m_data.append( 'file_attach', $('input[name=file_attach]')[0].files[0]);
//instead of $.post() we are using $.ajax()
//that's because $.ajax() has more options and flexibly.
$.ajax({
url: '/videoupload',
data: m_data,
processData: false,
contentType: false,
type: 'POST',
//dataType:'json',
datatype:'json',
success: function(response){
//load json data from server and output message
if(response.type == 'error'){ //load json data from server and output message
output = '<div class="error">'+response.text+'</div>';
}else{
output = '<div class="success">'+response.text+'</div>';
}
$("#videoform #form_results").hide().html(output).slideDown();
}
});
}
});
Using Firebug and the Net window, I can confirm that data entered in the fields of the form and the attached file are being appended to the FormData()
object.
When the user clicks Submit button, I get the following error in the Console:
> POST http://127.0.0.1:8000/videoupload 400 (BAD REQUEST)
send @ jquery.js:9664
m.extend.ajax @ jquery.js:9215
(anonymous function) @ videoupload:137
n.event.dispatch @ jquery.min.js:3
r.handle @ jquery.min.js:3
Navigated to http://127.0.0.1:8000/videoupload?videoTitle=asdf&videoDescription=asdfasdfasdfasdfasdf&videoTags=ZcZXcZXcZXcZXC&file_attach=ScreenCaptureProject1.mp4
In the Terminal window running Flask app (using Gunicorn) running in debug mode, no errors appear:
[2016-05-20 00:18:21 -0400] [27033] [DEBUG] POST /videoupload
POST CALLED
[2016-05-20 00:18:24 -0400] [27033] [DEBUG] GET /videoupload
It seems as though the AJAX is pinging the Flask view with a POST request. Am I handling the form incorrectly in the Flask view? Is there something incorrect with the JQuery AJAX POST request that Flask doesn't like?
Upvotes: 1
Views: 1616
Reputation: 2550
request.form
is a MultiDict with the key-value pairs of the received form data.
You are attempting to index this dictionary using the string 'm_data'
as a key, but it looks like 'm_data' is just the name of your JavaScript variable and not actually a key of the form data. If 'm_data'
is not a valid key this would raise an exception.
To quote the Werkzeug documentation on MultiDicts:
"From Werkzeug 0.3 onwards, the KeyError raised by this class is also a subclass of the BadRequest HTTP exception and will render a page for a 400 BAD REQUEST if caught in a catch-all for HTTP exceptions."
To help debug this route, you can wrap your python code in a try-except block:
@main.route('/videoupload', methods=['GET','POST'])
def videoupload():
if request.method == 'POST':
try:
[your code]
except Exception, e:
print e
return render_template('videoupload.html')
Then you can check whether a KeyError
appears in the error logs (or console if you're running the Flask test server locally).
Upvotes: 1