当前位置: 移动技术网 > IT编程>网页制作>Html5 > HTML5应用之文件上传

HTML5应用之文件上传

2019年07月25日  | 移动技术网IT编程  | 我要评论

呼斯楞退赛,1.bb5522.ws,全国贫困县

长期以来,开发者们一直为此苦恼,大部分为解决这个问题都采用了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的美化等等。不过这就不是我们这篇文章的主题了。

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

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网