39

Hi I'm quite new to flask and I want to upload a file using an ajax call to the server. As mentioned in the documentation, I added a file upload to the html as folows:

<form action="" method=post enctype="multipart/form-data" id="testid"> <table> <tr> <td> <label>Upload</label> </td> <td> <input id="upload_content_id" type="file" name="upload_file" multiple> <input type="button" name="btn_uplpad" id="btn_upload_id" class="btn-upload" value="Upload"/> </td> </tr> </table> </form> 

and I wrote the ajax handler as this

$(document).ready(function() { $("#btn_upload_id" ).click(function() { $.ajax({ type : "POST", url : "/uploadajax", cache: false, async: false, success : function (data) {}, error: function (XMLHttpRequest, textStatus, errorThrown) {} }); }); }); 

I do not know how to get the uploaded file (not the name) from this

 <input id="upload_content_id" type="file" name="upload_file" multiple> 

and save the file in folder. I'm not quite sure how to read the file from handler which i have written:

@app.route('/uploadajax', methods = ['POST']) def upldfile(): if request.method == 'POST': file_val = request.files['file'] 

I will be grateful if anyone can help. Thank you in advance

1
  • You can have a look at this post which suggests a flask-sijax to handle that stackoverflow.com/questions/14416706/… Commented Aug 20, 2013 at 12:21

3 Answers 3

69

To answer your question...

HTML:

<form id="upload-file" method="post" enctype="multipart/form-data"> <fieldset> <label for="file">Select a file</label> <input name="file" type="file"> </fieldset> <fieldset> <button id="upload-file-btn" type="button">Upload</button> </fieldset> </form> 

JavaScript:

$(function() { $('#upload-file-btn').click(function() { var form_data = new FormData($('#upload-file')[0]); $.ajax({ type: 'POST', url: '/uploadajax', data: form_data, contentType: false, cache: false, processData: false, success: function(data) { console.log('Success!'); }, }); }); }); 

Now in your flask's endpoint view function, you can access the file's data via flask.request.files.

On a side note, forms are not tabular data, therefore they do not belong in a table. Instead, you should resort to an unordered list, or a definition list.

Sign up to request clarification or add additional context in comments.

9 Comments

Can you explain the code: new FormData($('#upload-file')[0]); What does the "0" means?
Use Firebug, or whichever developer tools you use to bring up you browser's console. Now, in your JavaScript file: console.log($("#upload-file")); - As you can see, it returns an object. Suffixing with "[0]" selects the first item in the object. FormData(<first item in object>) creates a new FormData object, which is the object needed to send to your server.
I confirm that this should be the accepted answer. Works like charm! :) Thanks @onosendi!
As for your side note: unfortunatelly, given CSS current state (), it is still an order of magnitude easier to have the input fields aligned one to another with a table than using other techniques. () It simply seens to be a missing use case on the CSS2 and 3 specs - -either that, or tables are indeed expected.
@onosendi tried to use your answer with some AJAX, do U know what I'm doing wrong here? stackoverflow.com/questions/36995516/… Thank you in advance!
|
7

JavaScript (client side):

var form_data = new FormData(); form_data.append('file', $('#uploadfile').prop('files')[0]); $.ajax({ type: 'POST', url: '/uploadLabel', data: form_data, contentType: false, cache: false, processData: false, success: function(data) { console.log('Success!'); }, }); 

Python (server side):

@app.route('/uploadLabel', methods=['GET', 'POST']) def uploadLabel(): isthisFile = request.files.get('file') print(isthisFile) print(isthisFile.filename) isthisFile.save('./' + isthisFile.filename) 

Comments

0

I faced a problem where the saved file was being empty, it turned out to be because of the pointer. Since I could not find anyone that mentioned this, here is a suggestion:

Files in a FormData request can be accessed at request.files then you can select the file you included in the FormData e.g. request.files['audio'].

So now if you want to access the actual bytes of the file, in our case 'audio' using .stream, you should make sure first that your cursor points to the first byte and not to the end of the file, in which case you will get empty bytes.

Hence, a good way to do it:

file = request.files['audio'] file.stream.seek(0) audio = file.read() 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.