• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    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、允许设置请求的超时

    在这篇教程中,我们主要关注第一和第二项特性,尤其是第二项——它能够提供我们想要的上传进度。和之前的方案不同,这个方案并不要求服务器作出特殊的设置,因此大家边看教程就可以边动手试试了。

    上面图示的就是我们能够实现的内容:

    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">
    <div class="row">
          <label for="fileToUpload">Select a File to Upload</label>
    <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>
    
    

    JavaScript

    一旦我们在HTML中使用了input,我们就可以在JS代码中获取到一个FileList对象。这个对象是HTML5中新增加的文件API中的一部分,每一个FileList对象都是一组文件对象的集合,而文件对象则拥有下列的属性:

    1、name – 文件名(不包含路径)

    2、type – 文件的MIME类型(小写)

    3、size – 文件的尺寸(单位为字节)

    这正是我们所需要的。当然,HTML5中还有一个FileReader对象,但在这里我们并没有用它。现在,通过上面的三个内容,我们已经能够控制用户上传的文件大小和文件类型,以便减轻服务器再次检测时的压力,并提升安全系数。

     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 xhr = new XMLHttpRequest();
      var fd = document.getElementById('form1').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('progressNumber').innerHTML = percentComplete.toString() + '%';
      }
      else {
        document.getElementById('progressNumber').innerHTML = 'unable to compute';
      }
    }
    
    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('fileToUpload').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('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", "UploadMinimal.aspx");
            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) {
            /* 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">
    <div class="row">
          <label for="fileToUpload">Select a File to Upload</label>
    <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>

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

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

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    上一篇:html5+CSS3+JS实现七夕言情功能代码
    下一篇:HTML5+CSS3实现无插件拖拽上传图片(支持预览与批量)
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    HTML5应用之文件上传 HTML5,应,用之,文件,上传,