In the aritcle How to upload multiple files with python flask, we showed how to upload with html form.
In this aritcle, we will show how to upload in the "drag and drop" way. In this way, we can also show progress and speed during uploading.
In the following sections, we aussume that the url /upload
handles uploading.
You may need to change /upload
to your own url.
<div id="drop_area" style="padding:100px; border: 1px solid black">
Drag and drop your files here to upload.
</div>
<div id="upload_progress"></div>
<div id="speed"></div>
drop_area
will be used to receive files.upload_progress
will be used to show uploading progress.speed
will be used to show uploading speed.// prevent the default behavior of web browser
['dragleave', 'drop', 'dragenter', 'dragover'].forEach(function (evt) {
document.addEventListener(evt, function (e) {
e.preventDefault();
}, false);
});
var drop_area = document.getElementById('drop_area');
drop_area.addEventListener('drop', function (e) {
e.preventDefault();
var fileList = e.dataTransfer.files; // the files to be uploaded
if (fileList.length == 0) {
return false;
}
// we use XMLHttpRequest here instead of fetch, because with the former we can easily implement progress and speed.
var xhr = new XMLHttpRequest();
xhr.open('post', '/upload', true); // aussume that the url /upload handles uploading.
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
// uploading is successful
alert('Successfully uploaded!'); // please replace with your own logic
}
};
// show uploading progress
var lastTime = Date.now();
var lastLoad = 0;
xhr.upload.onprogress = function (event) {
if (event.lengthComputable) {
// update progress
var percent = Math.floor(event.loaded / event.total * 100);
document.getElementById('upload_progress').textContent = percent + '%';
// update speed
var curTime = Date.now();
var curLoad = event.loaded;
var speed = ((curLoad - lastLoad) / (curTime - lastTime) / 1024).toFixed(2);
document.getElementById('speed').textContent = speed + 'MB/s'
lastTime = curTime;
lastLoad = curLoad;
}
};
// send files to server
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
var fd = new FormData();
for (let file of fileList) {
fd.append('files', file);
}
lastTime = Date.now();
xhr.send(fd);
}, false);
import os
from flask import request
from werkzeug.utils import secure_filename
@app.route('/upload', methods=('POST',))
def upload():
files = request.files.getlist('files')
for file in files:
fn = secure_filename(file.filename)
file.save(os.path.join(FILES_DIR, fn)) # replace FILES_DIR with your own directory
return 'ok' # change to your own logic
Things you should notice about the flask code above:
methods
must include POST
request.files.getlist('files')
instead of request.files['files']
, because the latter is only used when uploading a single file.secure_filename
to prevent malicious file name.