初识html5 File API实现带有进度提示的文件上传

Html5终于解决了上传文件的同时显示文件上传进度的老问题。如今大部分的网站用Flash去实现这一功能,还有一些网站继续采用Html <form>with enctype=multipart/form-data,可是须要修改服务器端可用才能显示给用户文件上传的进度。本质上你须要作的工做是在服务器端接收一个文件时,你发送给它一个字节流,因此你须要知道你已经接收到多少字节并以某种方式传达这些信息给客户端浏览器,在这个过程一直在不断的进行文件的上传。这种方式运行的很是好,不像Flash上传那这样充满了问题(特别是处理大文件上传的时候),然而这种方法是至关复杂的而且听起来不容易理解,由于你本质上是接管了整个服务器端的处理(获取字节流的时候)同时包括了在服务器端实现multipart/form-data协议,伴随一系列的其余事情。javascript

使用Html5 上传文件

XMLHttpRequest 在Html5 规范中已经有全新的变化,规定了XMLHttpRequest Level 2规范(目前最新版本)包含下列新的特性:html

  1. 处理字节流,例如做为上传或者下载的File,Blob,FormData对象
  2. 上传或者下载中的进度事件
  3. 跨站点请求
  4. 容许建立匿名请求
  5. 能够设置请求超时

在这篇文章中咱们将可以更清楚的看到#1和#2两个特性。一般,上传文件用XMLHttpRequest而且提供上传进度信息给最终的用户,须要注意的是这种方式解决了不须要服务器端作任何改变,至少是目前处理multipart/form-data协议。因此服务器端的处理逻辑保留不变,这使得开发者适应这种技术至关容易。java

enter image description here 图1:文件上传画面-准备上传 enter image description here 图2:显示上传完成画面浏览器

注意:上面的图片中,信息提示区域是提供给用户的:服务器

  1. 当前选中文件的信息
    • 文件名
    • 文件大小
    • 文件类型
  2. 上传完成多少的百分比进度条
  3. 上传速度或者上传带宽
  4. 距离上传完成大概还有多长时间
  5. 已上传文件大小
  6. 服务器端的响应

上面第6项或许看起来不重要,但事实上是至关重要的。由于咱们用XMLHttpRequest,上传发生在后台,页面没有发生跳转等任何变化,因此对于你用它处理其余一些事情来讲是一个很是好的特性。app

Html5 Progress Event

对于Html5 Progress Events规范,Html5 Progess Events提供了下列与本次讨论相关的信息post

  1. total - 总的字节数
  2. loaded - 到目前为止上传的字节数
  3. lengthComputable - 可计算的已上传字节

请注意到咱们须要用两个信息去计算要显示给用户的其余全部信息。要计算出来其余的信息经过上面咱们获得信息是至关容易的,可是那须要一些额外的代码而且建立一个定时器。网站

Html5 Progress Event 应该是什么

考虑到有一部分人想更好的提供给用户全部的信息,因此Html5 Progress Event应该更好的知足须要,由于它给浏览器供应商提供这些额外信息是至关简单的,因此建议progress event应该修改为以下:spa

  1. total - 总的字节数
  2. loaded - 到目前为止上传的字节数
  3. lengthComputable - 可计算的已上传字节
  4. transferSpeed long类型
  5. timeRemaining JavaScript 日期对象

Html5 上传 用XMLHttpRequest

浏览器支持状况

支持这一特性的浏览器最低版本code

  1. Firefox 4.0 beta 6
  2. Chrome 6
  3. Safari 5.02

IE 9 Beta and Opera 10.62 不支持这一特性

简单的示例

下面是一个完整的Html页面包含了实现文件上传并带有进度提示的JavaScript代码,只是实现了基本的功能,感兴趣的能够本身作扩展。 须要吧上传接口修改为本身服务的。 

 

<!DOCTYPE html>
<html>
<head>
    <title>Upload Files using XMLHttpRequest - Minimal</title>
    <script type="text/javascript">
      function fileSelected() {
        var file = document.getElementById('fileToUpload').files[0];
        if (file) {
          var fileSize = 0;
          if (file.size > 1024 * 1024)
            fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100).toString() + 'MB';
          else
            fileSize = (Math.round(file.size * 100 / 1024) / 100).toString() + 'KB';
          document.getElementById('fileName').innerHTML = 'Name: ' + file.name;
          document.getElementById('fileSize').innerHTML = 'Size: ' + fileSize;
          document.getElementById('fileType').innerHTML = 'Type: ' + file.type;
        }
      }
      function uploadFile() {
        var fd = new FormData();
        fd.append("fileToUpload", document.getElementById('fileToUpload').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", "upload.do");//修改为本身的接口
        xhr.send(fd);
      }
      function uploadProgress(evt) {
        if (evt.lengthComputable) {
          var percentComplete = Math.round(evt.loaded * 100 / evt.total);
          document.getElementById('progressNumber').innerHTML = percentComplete.toString() + '%';
        }
        else {
          document.getElementById('progressNumber').innerHTML = 'unable to compute';
        }
      }
      function uploadComplete(evt) {
        /* 服务器端返回响应时候触发event事件*/
        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.aspx">
    <div class="row">
      <label for="fileToUpload">Select a File to Upload</label><br />
      <input type="file" name="fileToUpload" id="fileToUpload" onchange="fileSelected();"/>
    </div>
    <div id="fileName"></div>
    <div id="fileSize"></div>
    <div id="fileType"></div>
    <div class="row">
      <input type="button" onclick="uploadFile()" value="Upload" />
    </div>
    <div id="progressNumber"></div>
  </form>
</body>
</html>
相关文章
相关标签/搜索