よくあるやつ。昔はFlash使ってたけど、最近はHTML5でやった方が軽くてよさげ。 受け取り側は.net MVCで。
■HTML
<div> <div id="drop_zone" style="width:500px;border : 2px dashed #808080;margin:10px;padding:10px;"> <span>ファイルをココにドロップ</span> <progress id="testprogress" value="0" max="100">0%</progress> </div> </div>
■JavaScript
<script type="text/javascript"> //必要なのが使えるかチェック if (window.File && window.FileReader && window.FileList && window.Blob && window.FormData) { //OK } else { alert('ブラウザ変えてやり直し.'); } function handleFileSelect(evt) { //ブラウザのデフォルトの動作をキャンセル evt.stopPropagation(); evt.preventDefault(); var files = evt.dataTransfer.files;//ドロップイベントでドロップされたファイル var fd = new FormData();//送信用Formデータ for (var i = 0, f; f = files[i]; i++) { fd.append('files', f);//送信用Formデータに追加。キーの名前はコントローラの引数の名前と合わせておかないとダメ } AjaxPost(fd);//Ajaxでファイル送信 } function handleDragOver(evt) { //ブラウザのデフォルトの動作をキャンセル evt.stopPropagation(); evt.preventDefault(); evt.dataTransfer.dropEffect = 'copy'; } //送信 function AjaxPost(fd) { $.ajax({ type: "POST", url: "/Upload/TestUp", xhr: function () {//送信の進捗やりたいとき XHR = $.ajaxSettings.xhr(); if (XHR.upload) { XHR.upload.addEventListener('progress', function (e) { progre = parseInt(e.loaded / e.total * 10000) / 100; document.getElementById("testprogress").value = progre; }, false); } return XHR; }, processData: false, contentType: false, data: fd, success: function (dataobj) { console.log(dataobj); }, error: function (XMLHttpRequest, textStatus, errorThrown) { console.log(XMLHttpRequest) } }); } var dropZone = document.getElementById('drop_zone'); dropZone.addEventListener('dragover', handleDragOver, false); dropZone.addEventListener('drop', handleFileSelect, false); </script>
■Controler
[HttpPost] public ActionResult TestUp(HttpPostedFileBase[] files) { //filesにファイルが全部入ってるから後は保存でもなんでも好きにやる。 return View();//きっと成功したらなんか返した方がいいけどとりあえず。 }
ほんとはフォルダドロップで中のファイルを一括でとかにも対応したいんだけど、 割と面倒そうなので、ファイル複数選択してドロップ。今度、フォルダもやる。