首頁 > web前端 > H5教程 > 主體

HTML5應用程式之檔案上傳的詳細介紹

黄舟
發布: 2017-03-27 16:39:21
原創
2289 人瀏覽過

這篇文章主要介紹了HTML5應用程式之檔案上傳,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟著小編過來看看吧.

長期以來,開發者們一直為此苦惱,大部分為解決這個問題都採用了flash作為解決方案,但flash並非靈丹妙藥,因為flash版本,割據造成的問題有時反而變成了惡夢。有些網站則採用了form標籤的enctype=multipart/form-data屬性,但這一屬性要求伺服器作出特殊的設定才能夠顯示進度,而且本身也比較複雜,複雜就意味著容易出現錯誤,這可不是我們想要的。

現在我們來看看Html5為什麼能夠解決這個問題,以及,它到底能做的多好。

用HTML5上傳檔案

在HTML5標準中,XMLHttpRequest物件被重新定義,被稱為“XMLHttpRequest Level 2”,其中包含了以下5個新功能:

1、支援上傳、下載位元組流,例如檔案、blob以及表單資料

2、增加了上傳、下載中的進度事件

3、跨域請求的支援

4、允許發送匿名請求(即不發送HTTP的Referer部分)

#5、允許設定請求的逾時

在這篇教程中,我們主要關注第一和第二項特性,尤其是第二項——它能夠提供我們想要的上傳進度。和之前的方案不同,這個方案並不要求伺服器做出特殊的設置,因此大家邊看教學就可以邊動手試試了。

HTML5應用程式之檔案上傳的詳細介紹

HTML5應用程式之檔案上傳的詳細介紹

上面圖示的就是我們能夠實現的內容:

1、顯示上傳的檔案訊息,例如檔案名稱、類型、尺寸

2、一個能夠顯示真實進度的進度條

3、上​​傳的速度

4、剩餘時間的估算

5、已上傳的資料量

6、上傳結束後伺服器傳回的回應

另外,憑藉XMLHttpRequest,我們的上傳過程整個都是異步的,因此使用者在上傳檔案的時候,依然可以操作網頁當中的其它元素,並不需要專門等待上傳的完成。而在上傳結束後,我們能夠取得伺服器傳回的回應,因此整個上傳過程都顯得相當順理成章。

HTML5的進度事件

HTML5當中新增了進度事件(Progress Events),這個事件為我們提供了以下資訊:

1、total – 檔案大小

2、loaded – 已上傳的大小

3、lengthComputable – 進度是否可計算

資訊不多,但是在計算文件進度上已經足夠了。當然,也還有很多東西它沒有直接給出,這非常遺憾。

HTML

與普通的檔案上傳程式碼並沒有太大差異。不過注意,input標籤關聯了一個JavaScript函數在onchange上。


 <!DOCTYPE html>
<html>
<head>
    <title>使用XMLHttpRequest上传文件</title>
</head>
<body>
<form id="form1" enctype="multipart/form-data" method="post" action="upload.php">
<p class="row">
      <label for="fileToUpload">Select a File to Upload</label>
<input type="file" name="fileToUpload" id="fileToUpload" onchange="fileSelected();"/>
    </p>
<p id="fileName"></p>
<p id="fileSize"></p>
<p id="fileType"></p>
<p class="row">
<input type="button" onclick="uploadFile()" value="Upload" />
    </p>
<p id="progressNumber"></p>
</form>

</body>
</html>
登入後複製

JavaScript

#一旦我們在HTML中使用了input,我們就可以在JS程式碼中取得到一個FileList對象。這個物件是HTML5中新增加的檔案API中的一部分,每個FileList物件都是一組檔案物件的集合,而檔案物件則擁有下列的屬性:

1、name – 檔案名稱(不包含路徑)

2、type – 檔案的MIME類型(小寫)

3、size – 檔案的尺寸(單位為位元組)

這正是我們所需要的。當然,HTML5中還有一個FileReader對象,但這裡我們並沒有用到它。現在,透過上面的三個內容,我們已經能夠控制使用者上傳的檔案大小和檔案類型,以便減輕伺服器再次偵測時的壓力,並提升安全係數。


 function fileSelected() {
  var file = document.getElementById(&#39;fileToUpload&#39;).files[0];
  if (file) {
    var fileSize = 0;
    if (file.size > 1024 * 1024)
      fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100).toString() + &#39;MB&#39;;
    else
      fileSize = (Math.round(file.size * 100 / 1024) / 100).toString() + &#39;KB&#39;;

    document.getElementById(&#39;fileName&#39;).innerHTML = &#39;Name: &#39; + file.name;
    document.getElementById(&#39;fileSize&#39;).innerHTML = &#39;Size: &#39; + fileSize;
    document.getElementById(&#39;fileType&#39;).innerHTML = &#39;Type: &#39; + file.type;
  }
}
登入後複製

那麼當使用者選擇好文件,點擊上傳之後,又會發生什麼?


 function uploadFile() {
  var xhr = new XMLHttpRequest();
  var fd = document.getElementById(&#39;form1&#39;).getFormData();

  /* event listners */
  xhr.upload.addEventListener("progress", uploadProgress, false);
  xhr.addEventListener("load", uploadComplete, false);
  xhr.addEventListener("error", uploadFailed, false);
  xhr.addEventListener("abort", uploadCanceled, false);
  /* Be sure to change the url below to the url of your upload server side script */
  xhr.open("POST", "upload.php");
  xhr.send(fd);
}

function uploadProgress(evt) {
  if (evt.lengthComputable) {
    var percentComplete = Math.round(evt.loaded * 100 / evt.total);
    document.getElementById(&#39;progressNumber&#39;).innerHTML = percentComplete.toString() + &#39;%&#39;;
  }
  else {
    document.getElementById(&#39;progressNumber&#39;).innerHTML = &#39;unable to compute&#39;;
  }
}

function uploadComplete(evt) {
  /* This event is raised when the server send back a response */
  alert(evt.target.responseText);
}

function uploadFailed(evt) {
  alert("There was an error attempting to upload the file.");
}

function uploadCanceled(evt) {
  alert("The upload has been canceled by the user or the browser dropped the connection.");
}
登入後複製

在程式碼的第二行中,我們的JS程式碼又使用了另一個HTML5推出的新物件-FormData。 FormData物件是使用者的表單資料的集合,它以鍵值對的形式儲存了表單數據,其值能夠包括數字、字串以及檔案。我們透過輾轉這個對象,來向伺服器提交資料。

當然,這個物件我們也可以在程式碼中手動構建,比如說像下面這樣:


var fd = new FormData();
fd.append("author", "Shiv Kumar");
fd.append("name", "Html 5 File API/FormData");
fd.append("fileToUpload", document.getElementById(&#39;fileToUpload&#39;).files[0]);
登入後複製

回到正題。回顧上一段程式碼,我們增加了許多有關XMLHttpRequest的事件監聽,其目的是為了取得檔案上傳的真實情況。尤其要注意的是,我們所掛鉤的,並不是XMLHttpRequest本身,而是其屬性,例如uploadProgress。

完整程式碼

最後,來看看完整的程式碼。


 <!DOCTYPE html>
<html>
<head>
    <title>Upload Files using XMLHttpRequest - Minimal</title>

    <script type="text/javascript">
      function fileSelected() {
        var file = document.getElementById(&#39;fileToUpload&#39;).files[0];
        if (file) {
          var fileSize = 0;
          if (file.size > 1024 * 1024)
            fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100).toString() + &#39;MB&#39;;
          else
            fileSize = (Math.round(file.size * 100 / 1024) / 100).toString() + &#39;KB&#39;;

          document.getElementById(&#39;fileName&#39;).innerHTML = &#39;Name: &#39; + file.name;
          document.getElementById(&#39;fileSize&#39;).innerHTML = &#39;Size: &#39; + fileSize;
          document.getElementById(&#39;fileType&#39;).innerHTML = &#39;Type: &#39; + file.type;
        }
      }

      function uploadFile() {
        var fd = new FormData();
        fd.append("fileToUpload", document.getElementById(&#39;fileToUpload&#39;).files[0]);
        var xhr = new XMLHttpRequest();
        xhr.upload.addEventListener("progress", uploadProgress, false);
        xhr.addEventListener("load", uploadComplete, false);
        xhr.addEventListener("error", uploadFailed, false);
        xhr.addEventListener("abort", uploadCanceled, false);
        xhr.open("POST", "UploadMinimal.aspx");
        xhr.send(fd);
      }

      function uploadProgress(evt) {
        if (evt.lengthComputable) {
          var percentComplete = Math.round(evt.loaded * 100 / evt.total);
          document.getElementById(&#39;progressNumber&#39;).innerHTML = percentComplete.toString() + &#39;%&#39;;
        }
        else {
          document.getElementById(&#39;progressNumber&#39;).innerHTML = &#39;unable to compute&#39;;
        }
      }

      function uploadComplete(evt) {
        /* This event is raised when the server send back a response */
        alert(evt.target.responseText);
      }

      function uploadFailed(evt) {
        alert("There was an error attempting to upload the file.");
      }

      function uploadCanceled(evt) {
        alert("The upload has been canceled by the user or the browser dropped the connection.");
      }
    </script>
</head>
<body>
<form id="form1" enctype="multipart/form-data" method="post" action="upload.php">
<p class="row">
      <label for="fileToUpload">Select a File to Upload</label>
<input type="file" name="fileToUpload" id="fileToUpload" onchange="fileSelected();"/>
    </p>
<p id="fileName"></p>
<p id="fileSize"></p>
<p id="fileType"></p>
<p class="row">
<input type="button" onclick="uploadFile()" value="Upload" />
    </p>
<p id="progressNumber"></p>
</form>

</body>
</html>
登入後複製

我们的任务完成了吗?可以说完成了,因为这段代码已经能够完成上传文件的任务,而且也能够显示上传的进度;但是理应说我们没有,因为除了这个骨架HTML之外,我们还有很多没有做的事情,比如CSS的美化等等。不过这就不是我们这篇文章的主题了。

最后,提醒一下,教程的代码应当在支持新特性的浏览器之上运行,如果你不清楚自己的浏览器是否支持,可以在这里查询。

相关文章:

移动端通过HTML5实现文件上传功能

php中文件上传图片

JavaScript进阶(九)JS实现本地文件上传至阿里云服务器

以上是HTML5應用程式之檔案上傳的詳細介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn