How to upload a file using an ajax call in flask

Question:

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

Asked By: 0x12

||

Answers:

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.

Answered By: user2709610

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)
Answered By: 蘇韋文

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()
Answered By: Bourhano
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.