简体   繁体   中英

File upload using Flask and jQuery

I am having trouble writing a program for sending html form using an ajax call in jQuery. Here is my upload.html and form.js file:

 $(document).ready(function() { $('form').on('submit', function(event) { $.ajax({ type : 'POST', url : '/uploadhc', data : $('#hc') }) .done(function(data) { if (data.error) { $('#errorAlert').text(data.error).show(); $('#successAlert').hide(); } else { $('#successAlert').text(data.file).show(); $('#errorAlert').hide(); } }); event.preventDefault(); }); });
 <!DOCTYPE html> <html lang="en"> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> <meta charset="UTF-8"> <title>File Upload</title> <script type=text/javascript src="{{ url_for('static', filename='form.js') }}"></script> </head> <body> <h1>Please upload all the corresponding files</h1> <div id="upload"> <form id="upload-hc" > <input type="file" name="file" accept=".csv" id="hc"> <input type="submit" value="go"> </form> <br> <p id="successAlert" style="display:none;">Success!</p> <p id="errorAlert" style="display:none;">Fail!</p> </div> <script> </script> </body> </html>

Here is my Flask server:

import os
from flask import Flask, render_template, request, jsonify

app = Flask(__name__)
APP_ROOT = os.path.dirname(os.path.abspath(__file__))

@app.route("/")
def index():
    return render_template("upload.html")


@app.route("/uploadhc", methods=['POST'])
def uploadhc():
    target = os.path.join(APP_ROOT, "DataSource/")


    if not os.path.isdir(target):
        os.mkdir(target)
    print request.files
    if 'file' not in request.files:
        error = "Missing data source!"
        return jsonify({'error': error})


    file = request.files['file']
    fileName = "DCData.csv"
    destination = '/'.join([target, fileName])
    file.save(destination)


    success = "Success!"
    return jsonify({'file': success})


if __name__ == "__main__":
    app.run(port=4555, debug=True)

When I try to select a csv file and submit the HTML form, the server says the request.files is ImmutableMultiDict([]), which is empty. Any idea how to send the file to my server? Thanks!

You need to send the form as multipart upload, you can transform the entier form to that with FormData(formElement)

var form = $('#upload-hc')[0]
var fd = new FormData(form)

$.ajax({
  type : 'POST',
  url : '/uploadhc',
  data: fd,
  processData: false,  // tell jQuery not to process the data
  contentType: false   // tell jQuery not to set contentType
})

Here you got a es6 version if you would be interested

 // short for jquery(function($){ ... }) // which is the equvilant to $(document).ready(function($) { jQuery($ => { $('form').on('submit', event => { event.preventDefault() let form = $('#upload-hc')[0] let fd = new FormData(form) fetch('/uploadhc', {method: 'POST', body: fd}) .then(res => { // console.log(res.ok) return res.json() // or res.text, res.arraybuffer }) .then(result => { console.log(result) }) }) })

In the html side:

<input type="file" id="uploadfile" name="NewCsvUpload">

In the javascript side:

var form_data = new FormData();
form_data.append('file', $('#uploadfile').prop('files')[0]);

$(function() {
$.ajax({
    type: 'POST',
    url:  '/uploadLabel',
    data: form_data,
    contentType: false,
    cache: false,
    processData: false,
    success: function(data) {
        console.log('Success!');
    },
  })
});

In the server side:

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

When I've done this in the past, I've always put enctype="multipart/form-data" in the form div.

Here a couple of links that explain it in further detail:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM