主選單

2017-05-18

C#:拖曳上傳檔案 (drag and drop file uploading)

在網頁上製作一個區塊,將檔案拖曳過去後,可以自動上傳檔案到 Server 端。



網頁內容加入以下HTML,包含接受拖曳檔案的區塊 drop_block,以及顯示上傳進度的進度條 upload_progress。
<body>
    <div>
        <div id="drop_block" ondragover="javascript: drag_handler(event);" ondrop="javascript: drop_file(event);" class="upload-block">
            請將檔案拖曳到此...
            <div class="progress">
                <div id="upload_progress" class="progress-bar progress-bar-striped active" role="progressbar" aria-valuenow="" aria-valuemin="0" aria-valuemax="100">
                </div>
            </div>
        </div>
    </div>
</body>
外觀對應的 CSS 如下,因為進度條使用 bootstrap,所以也要引用 bootstrap.min.css。
<head>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
    <style type="text/css">
        .upload-block
         { 
             width: 300px; 
             height:200px; 
             border-style: dotted; 
             border-color: #999999;        
             text-align:center;
             padding: 20px;
             margin: 20px; 
        } 
        .dragover 
        { 
            border-color:#FF9900; 
        } 
        .progress 
        { 
            text-align:center;
            width: 100%; 
        } 
    </style>
</head>

主要的 JavaScript 如下。event.dataTransfer 是負責處理拖曳事件的物件,可以從中取得被拖曳檔案清單 (關於DataTransfer)。XMLHttpRequest 物件可將資料傳送出去, TestUpload.aspx 是準備要負責處理接收的網頁。
<script>
    function drop_file(e) 
    {
        e.preventDefault();
        var upload_image = document.getElementById('drop_block');
        var elProgress = document.getElementById('upload_progress');
        var images_container = document.getElementById('images_container');
        var objXhr  = new XMLHttpRequest();
        var files = e.dataTransfer.files;
        var objForm = new FormData();
        var sucess_count = 0;

        objXhr.upload.onprogress = function(e) 
        {
            if (e.lengthComputable) 
            {
                var intComplete = (e.loaded / e.total) * 100 | 0;

                elProgress.innerHTML = intComplete + '%';
                elProgress.style.width = intComplete + '%';

                elProgress.setAttribute('aria-valuenow', intComplete);
            }
        }

        objXhr.onload = function(e) 
        {
            upload_image.className = upload_image.className.replace(' dragover', '');
            elProgress.className = elProgress.className.replace(' active', '');

            alert(objXhr.responseText); //接收網頁回傳結果
        }

        objXhr.open('POST', 'TestUpload.aspx');
        for (var i = 0; i < files.length; i++) 
        {
            if (!files[i].type.match('image')) 
            {
                var name = files[i].name;
                alert(name + '格式不正確,須為圖檔!');
                continue;
            }
            objForm.append('images[]', files[i]);
            objForm.append('save_file', "Y");
        }

        objXhr.send(objForm);
    }
</script>
避免某些瀏覽器執行自己的預設動作,如自動開啟圖檔等...
<script>
    function drag_handler(e) 
    {
        var upload_image = document.getElementById('drop_block');
        var elProgress = document.getElementById('upload_progress');
        e.preventDefault();  //防止瀏覽器執行預設動作
        if (!upload_image.className.match('dragover')) 
        {
            upload_image.className = upload_image.className + ' dragover';
        }

        if (upload_progress.style.width != '0%') 
        {
            upload_progress.style.width = '0%';
        }
    }
</script>


後端可使用不同程式來接收,下面是使用 ASP.NET 3.5 的例子。
protected void Page_Load(object sender, EventArgs e)
{
    if (Request["save_file"] != null)
    {
        MyUpload();
        Response.Write("上傳完成");
        Response.End();
    }
}

protected void MyUpload()
{
    for (int i = 0; i < Request.Files.Count; i++)
    {
        HttpPostedFile postedFile = Request.Files[i];

        if (postedFile.ContentLength > 0)
        {
            string fileName = Path.GetFileName(postedFile.FileName);
            postedFile.SaveAs(Server.MapPath("~/Uploads/") + fileName);
        }
    }
}


原始參考資料(使用PHP):http://code-beginner.logdown.com/posts/313821


2 則留言:

  1. 謝謝,那如果上傳的檔案要改檔名呢? 如 AA.pdf 變成加了亂數 AA-5247.pdf 有辦法嗎? 不好意思,現在還是初學者。

    回覆刪除
  2. 不好意思,打擾您了。 後來有想出來了。


    var now = new Date();
    objForm.append('images[]', files[i], now.localeFormat("yyyyMMddhhmmss") + "-" + files[i].name); // 可以的
    objForm.append('save_file', "Y");

    回覆刪除