Upload multiple files using "drag and drop" with html5 and flask¶
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.
Assumption¶
In the following sections, we aussume that the url /upload
handles uploading.
You may need to change /upload
to your own url.
html¶
<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.
javascript¶
// 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);
Backend flask¶
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 includePOST
- To get files, you must use
request.files.getlist('files')
instead ofrequest.files['files']
, because the latter is only used when uploading a single file. - use
secure_filename
to prevent malicious file name.
This article is originally created by tooli.top. Please indicate the source when reprinting : https://www.tooli.top/posts/drag_drop_upload
Posted on 2022-04-01
Mail to author