首頁 >web前端 >H5教程 >html5檔案拖曳上傳的範例程式碼分享

html5檔案拖曳上傳的範例程式碼分享

黄舟
黄舟原創
2017-03-27 15:13:182209瀏覽

 

html5 文件拖曳上傳是個老話題了,網路上有很多例子,我一開始的程式碼也是網路找來改的,只是踩了幾個坑之後就想把過程記錄下來。

 

功能實作

以下主要介紹從瀏覽器外拖曳檔案到瀏覽器進行上傳的實作。 首先會介紹一些必須的基礎。

 

拖曳事件

拖曳事件有以下這些:

  • dragstart :當使用者開始拖曳物件時觸發。

  • dragenter: 當滑鼠第一次經過目標元素,且有拖曳發生時觸發。此事件的監聽者應指明在這個位置上是否允許drop,或監聽者不執行任何操作,那麼drop預設是不允許的。

  • dragover:當滑鼠經過一個元素時,且有拖曳發生時觸發 。

  • dragleave:當滑鼠離開一個元素,且有拖曳在發生時觸發。

  • drag: 當物件被拖曳,每次移動滑鼠時觸發。

  • drop:在drag操作的最後發生drop時,在元素上觸發此事件。監聽者應該負責檢索拖曳的數據,並插入drop的位置。

  • dragend: 拖曳物件時放開滑鼠按鍵時觸發。

從瀏覽器外拖曳檔案到瀏覽器時,必須綁定的事件有 dragover #和 drop,其他的都可以不綁定。 dragover drop 事件的處理函數內部必須呼叫事件的 <a href="http://www.php.cn/wiki/1074.html" target="_blank"></a>

############################################# ####prev###entDefault()###### ###函數,要不然瀏覽器會進行預設處理,例如文字類型的檔案直接打開,非文字的可能會彈出一個下載檔案框。 ###### ######DataTransfer物件######拖曳物件用來傳遞資料的媒介,透過拖曳事件的### ######event.dataTransfer#### ### ###取得。 ###
  • dataTransfer.dropEffect [ = value ]:傳回目前選擇的操作類型,可以設定新的值來修改已選擇的操作。可選的值有: none, <a href="http://www.php.cn/wiki/1297.html" target="_blank">copy</a>, link, move 

  • dataTransfer.effectAllowed [ = value ]:傳回允許的操作類型,可修改。可選的值有:none, copy, copyLink, copyMove, link, linkMove, move, all, uninitialized #。

  • dataTransfer.types:傳回一個DOMString,列出在dragstart事件裡設定的所有格式。另外,如果有檔案被拖曳,那麼其中一個類型的字串將是「Files」。

  • dataTransfer.clearData( [ format ] ):移除指定格式的資料。如果忽略參數則移除所有資料。

  • dataTransfer.setData(format, data):新增指定的資料。

  • data = dataTransfer.getData(format):傳回指定的資料。如果沒有這樣的數據,則傳回空字串。

  • dataTransfer.files:傳回被拖曳的FileList,如果有。

  • dataTransfer.setDragImage(element, x, y):用指定的元素來更新drag回饋,取代先前指定的回饋( feedback)。

  • dataTransfer.addElement(element):新增指定元素到用於渲染drag回饋的元素清單。

在這個用例裡,最重要的就是 #dataTransfer.files 屬性#它是使用者拖曳進瀏覽器的檔案列表,是個 FileList對象,有 length #屬性,可以透過下標存取。

 

FormData

FormData 代表表單,可以透過 append('fieldName', value) 函數在表單裡新增參數,參數的只不僅可以是字串,還可以是File對象,甚至是二進位資料。

 

XMLHttpRequest level 2

新版本的XMLHttpRequest對象,這裡說的XMLHttpRequest都是指新版的。

XMLHttpRequest可以向不同網域的伺服器發出HTTP請求。這叫做 「跨域資源共享」(Cross-origin resource sharing,簡稱CORS)。

 

瀏覽器有個著名的同源策略,這裡瀏覽器安全的基礎,CORS 除了需要瀏覽器支援外,還要伺服器同意。

XMLHttpRequest 支援直接傳送FormData,就像瀏覽器進行表單提交一樣。

 

XMLHttpRequest 也支援進度資訊(progress事件),進度分為上傳進度和下載進度,上傳進度的事件是在XMLHttpRequest.upload 物件上,下載進度的事件是在 XMLHttpRequest #」物件。每個進度事件都有三個屬性:

  • lengthComputable:可計算的已上傳位元組數

  • total:總的位元組數

  • loaded:到目前為止上傳的位元組數

除了進度事件,也支援以下五個事件:

  • load事件:傳輸成功完成。

  • abort事件:傳輸被使用者取消。

  • error事件:傳輸中出現錯誤。

  • loadstart事件:傳輸開始。

  • loadend事件:傳輸結束,但不知道成功還是失敗。

 progress事件一樣,屬於上傳作業的事件處理函數綁定在XMLHttpRequest.upload物件上,屬性下載的直接綁定在 XMLHttpRequest 物件。

 

具體程式碼

本機測試時要注意把下面程式碼裡的路徑改為自己本機的。

 

伺服器端

伺服器端需要寫個Servlet來接收上傳的表單。  /html5/FileUploadServlet

用servlet3的 @MultipartConfig 註解就可以很快實現。

 

客戶端程式碼

<html>
<head>
<title> drag drop upload demo
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
</head>
<body>
       <p id= "progressBarZone">请将文件拖拽进浏览器内! <br/></ p>
</body>

<script>
var progressBarZone = document.getElementById(&#39;progressBarZone&#39;);

function sendFile(files) {
       if (!files || files.length < 1) {
             return;
      }
      
       var percent = document.createElement(&#39;p&#39; );
      progressBarZone.appendChild(percent);

       var formData = new FormData();             // 创建一个表单对象FormData
      formData.append( &#39;submit&#39;, &#39;中文&#39; );  // 往表单对象添加文本字段
      
       var fileNames = &#39;&#39; ;
      
       for ( var i = 0; i < files.length; i++) {
             var file = files[i];    // file 对象有 name, size 属性
            
            formData.append( &#39;file[&#39; + i + &#39;]&#39; , file);       // 往FormData对象添加File对象
            
            fileNames += &#39;《&#39; + file.name + &#39;》, &#39; ;
      }
      
       var xhr = new XMLHttpRequest();
      xhr.upload.addEventListener( &#39;progress&#39;,
             function uploadProgress(evt) {
                   // evt 有三个属性:
                   // lengthComputable – 可计算的已上传字节数
                   // total – 总的字节数
                   // loaded – 到目前为止上传的字节数
                   if (evt.lengthComputable) {
    percent.innerHTML = fileNames + &#39; upload percent :&#39; + Math.round((evt.loaded / evt.total)  * 100) + &#39;%
&#39; ;
                  }
            }, false); // false表示在事件冒泡阶段处理

      xhr.upload.onload = function() {
            percent.innerHTML = fileNames + &#39;上传完成。

&#39; ;
      };

      xhr.upload.onerror = function(e) {
            percent.innerHTML = fileNames + &#39; 上传失败。

&#39; ;
      };

      xhr.open( &#39;post&#39;, &#39;http://cross.site.com:8080/html5/FileUploadServlet&#39; , true);
      xhr.send(formData);            
      // 发送表单对象。
}

document.addEventListener("dragover", function(e) {
      e.stopPropagation();
      e.preventDefault();            
      // 必须调用。否则浏览器会进行默认处理,比如文本类型的文件直接打开,非文本的可能弹出一个下载文件框。
}, false);

document.addEventListener("drop", function(e) {
      e.stopPropagation();
      e.preventDefault();            
      // 必须调用。否则浏览器会进行默认处理,比如文本类型的文件直接打开,非文本的可能弹出一个下载文件框。

      sendFile(e.dataTransfer.files);
}, false);
</script>
</html>

 

如果上面的程式碼都部署在同一個網站下,那是沒有問題的。可是我要做的上傳操作是要把文件傳到另一個網站上,坑也就產生了。

 

以上是html5檔案拖曳上傳的範例程式碼分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn