ライブラリなしでファイルをドラッグ&ドロップでアップロード
ライブラリなしでdropZoneを使ったファイルアップロードの記事が少なかったので書きました
注意
ライブラリなしと言ってますがajax通信にjQueryを使ってます
jQueryを使わない場合はこちらを参考にしつつ生jsで置き換えてください
ライブラリを使える人はこの記事の実装を参考にdropzone.jsというライブラリを使うといいかと思います
ドロップゾーンの実装
複数ファイルアップロードする場合はenctype=multipart/form-data
を入れてください
htmlの記述
<div id="drop_zone">Drop a file here</div>
<output id="list"></output>
<form id="my_form" enctype=multipart/form-data>
<input type="file" style="display:inline" name="upload_file">
<br>
<button type="button" onclick="file_upload()">アップロード</button>
</form>
見た目
自分のサイトに合わせて調整してみてください
# drop_zone{
width: 80%;
height: 200px;
border: 1px dotted black;
border-radius: 1rem;
margin: auto;
margin-top: 2rem;
font-size: 3rem;
}
dropzoneの処理
HTML5 rocksの記事を元に実装してます
詳しい解説は上の記事がわかりやすいです
//drop zoneの実装
function handleFileSelect(evt) {
evt.stopPropagation();
evt.preventDefault();
files = evt.dataTransfer.files; // FileList object.
// 以下に必要なFile Objectのプロパティを記述
var output = [];
for (var i = 0, f; f = files[i]; i++) {
output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ',
f.size, ' bytes, last modified: ',
f.lastModifiedDate.toLocaleDateString(), '</li>');
}
document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
}
function handleDragOver(evt) {
evt.stopPropagation();
evt.preventDefault();
evt.dataTransfer.dropEffect = 'copy';
}
// イベントリスナーを設定
var dropZone = document.getElementById('drop_zone');
dropZone.addEventListener('dragover', handleDragOver, false);
dropZone.addEventListener('drop', handleFileSelect, false);
ajax通信
requestの中身は{upload_file:(ファイルデータ)}
のようなjson形式で表されます
サーバーサイド側でjson形式のデータのように扱えます
function file_upload()
{
// フォームデータを取得
let formdata = () => new FormData($('#my_form').get(0));
// ファイルが未登録なら一番最初のファイルを追加
// 複数ファイルアップロードの場合ここを修正
if($('input[name="upload_file"]').val() == ""){
formdata.append('upload_file',files[0])
}
//非同期通信
$.ajax({
url : "/upload",
type : "POST",
data : formdata,
cache : false,
contentType : false,
processData : false,
dataType: 'html',
})
.done(function(data, textStatus, jqXHR){
console.log(data);
})
.fail(function(jqXHR, textStatus, errorThrown){
console.log("fail");
})
.always(function(data){
console.log("complete")
});
}
flaskの場合は以下の記述で取り出せます
file = request.files['upload_file']
-
他にもユーザー名等のパラメータがあった場合html上にinput要素を適宜追加してみてください
-
ちなみに複数ファイルの場合は
{{upload_file1:(ファイル1), upload_file2:(ファイル2)}
のような中身になります
参考