Kalanamith
Kalanamith

Reputation: 20648

How to upload a file using an ajax call in flask

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

Upvotes: 39

Views: 43660

Answers (3)

蘇韋文
蘇韋文

Reputation: 121

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)

Upvotes: 7

Bourhano
Bourhano

Reputation: 63

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()

Upvotes: 0

user2709610
user2709610

Reputation:

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.

Upvotes: 69

Related Questions