HTML5关于上传API的一些使用(上)

HTML5提供了很多有用的API,其中就包括上传的API,XMLHttpRequest2.0,在HTML5时代之前,需要进行二进制的上传一般都会才用flash的方案,但是当XMLHttpRequest2.0出来之后,完全可以使用HTML5的上传解决方案,能够非常方便的进行二进制上传进度的显示,上传图片的本地预览,甚至可以做到断点续传,分片上传,多文件上传等各种复杂的底层功能。


首先回顾一下XMLHttpRequest1.0的传输过程

关于XMLHttpRequest


初始化XMLHttpRequest

??想要使用XMLHttpRequest进行传输文件,首先我们得创建一个XMLHttpRequest对象, 而每创建一个XMLHttpRequest的时候会产生readyState这个属性,当一个 XMLHttpRequest 初次创建时,这个属性的值从 0 开始,直到接收到完整的 HTTP 响应,这个值增加到 4。 5 个状态中每一个都有一个相关联的非正式的名称,下表列出了状态、名称和含义:

状态 名称 描述
0 Uninitialized 初始化状态。XMLHttpRequest 对象已创建或已被 abort() 方法重置。 
1 Open open() 方法已调用,但是 send() 方法未调用。请求还没有被发送。
2 Sent?????  Send() 方法已调用,HTTP 请求已发送到 Web 服务器。未接收到响应。
3 Receiving 所有响应头部都已经接收到。响应体开始接收但未完成。
4 Loaded HTTP 响应已经完全接收。

?????

var xhr = new XMLHttpRequest(); //readyState为0

xhr.open方法设置初始参数

??然后需要初始化一些HTTP请求的参数但是这里只是初始化,也就是说设置一些上传所需要的参数,但是并不会进行上传

xhr.open(method, url, async, username, password); //readyState为1

method 参数是用于请求的 HTTP 方法。值包括 GET、POST 和 HEAD。

url 参数是请求的主体。大多数浏览器实施了一个同源安全策略,并且要求这个 URL 与包含脚本的文本具有相同的主机名和端口。

async 参数指示请求使用应该异步地执行。如果这个参数是 false,请求是同步的,后续对 send() 的调用将阻塞,直到响应完全接收。如果这个参数是 true 或省略,请求是异步的,且通常需要一个 onreadystatechange 事件句柄。

username 和 password 参数是可选的,为 url 所需的授权提供认证资格。如果指定了,它们会覆盖 url 自己指定的任何资格。

xhr.send()方法发送请求

??对HTTP的请求的参数设置完之后就可以进行发送了

xhr.send(); //readyState为2

??xhr.send()会导致一个HTTP请求。如果之前没有调用 open()或者说 readyState 不是 1,xhr.send() 则会跑出一个错误。否则,它发送一个 HTTP 请求,该请求由以下几部分组成: 之前调用xhr.open() 时指定的 HTTP 方法、URL 以及认证资格(如果有的话)。 之前调用 xhr.setRequestHeader() 时指定的请求头部(如果有的话)。 传递给这个方法的 body 参数。

??请求发布后,send() 把 readyState 设置为 2,并触发 onreadystatechange 事件。

关于 onreadystatechange 事件

??onreadystatechange实际上是每当readyState发生改变的时候就会触发的参数,也就是说我们可以直接在onreadystatechange事件中去判断readyState的值,假如readyState等于4的时候就可以执行上传完成后的回调方法。

??如果之前调用的xhr.open() 参数 async 为 false,这个方法会阻塞并不会返回,直到 readyState 为 4 并且服务器的响应被完全接收。否则,如果 async 参数为 true,或者这个参数省略了,xhr.send() 立即返回。如果服务器响应带有一个 HTTP 重定向,xhr.send() 方法或后台线程自动遵从重定向。当所有的 HTTP 响应头部已经接收,xhr.send() 或后台线程把 readyState 设置为 3 并触发 onreadystatechange 事件句柄。如果响应较长,xhr.send() 或后台线程可能在状态 3 中触发 onreadystatechange 事件句柄:这可以作为一个下载进度指示器。最后,当响应完成,xhr.send() 或后台线程把 readyState 设置为 4,并最后一次触发事件句柄。

通过上面的初始化,open,send,已经监控onreadystatechange事件的返回值用以触发回调方法,我们就完成了一个ajax请求。

关于XMLHttpRequest2.0



??而关于HTML5中增加XMLHttpRequest2.0的新功能主要包括下面这些:

  • 可以设置HTTP请求的时限。
  • 可以使用FormData对象管理表单数据。
  • 可以上传文件。
  • 可以请求不同域名下的数据(跨域请求)。
  • 可以获取服务器端的二进制数据。
  • 可以获得数据传输的进度信息。

我们这里主要说和上传文件比较密切相关的部分

关于FormData

??AJAX通常可以用来进行模拟表单的提交,也就是说XMLHttpRequest1.0中大家经常使用的无刷新提交数据,为了方便对于表单的处理,HTML新增了一个FormData对象,可以用来模拟表单。使用如下:

var formData=new FormData();
formData.append(‘name‘,"Jack");
formData.append(‘uid‘,666666);  

??上面的三行代码就实现了往一个FormData()对象里面插入了两个字段,一个name,一个uid 然后我们可以就像XMLHttpRequest1.0的时候一样进行ajax的提交即:

var xhr=new XMLHttpRequest();
xhr.open("post",url);
xhr.send(formData);  

关于HTML5多文件的上传



??那我们实际上想要用HTML5解决上传文件的过程应该怎么解决呢? HTML5中针对<input type="file"/>标签新加了一个files的对象,并且通过对input标签设置multiple属性,则可以实现添加多个文件的功能,而files实际上是一个数组对象,里面存的则全是这个file标签中的文件; 
??那么我们想要上传文件就很简单了,直接循环files对象获取到用户添加到file控件中的文件并且都通过FormData对象的append方法添加到FormData中去,然后进行发送即可。

var formData=new FormData();
for(var i=0;i<files.length;i++){
    formData.append(i,files[i]);
}
var xhr=new XMLHttpRequest();
xhr.open("post",url);
xhr.send(formData);  

通过上面这些代码就可以实现对于多文件的上传了。

关于HTML5上传中的各种需求



虽然上面实现了对于多个文件的上传,但是大家在实际工作中对于上传的需求肯定不单单是能够上传而已,下面我们就来说下利用HTML5对于上传API中新增加的一大堆好用的东西所能够实现的效果;

上传之前的本地预览

??大家在做文件上传之前,经常会碰到需要预览文件大小,文件名称等信息,关于这些HTML5已经帮我们封装好了相应的API,我们只需要调用方法即可 上面说到关于<input type="file" />标签中有一个files数组对象,实际上这个数组对象中的每一个值都有一些相应的属性可以调用

  • name – 文件名(不包含路径)
  • type – 文件的MIME类型(小写)
  • size – 文件的尺寸(单位为字节)

通过调用上面的三个属性就可以获得每一个文件在本地的一些相关信息,相关方法如下

function fileSelected() {
    var file = document.getElementById(‘fileToUpload‘).files[0];        //获取到上传控件对象files
    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;
    }
}

关于FileReader

??关于本地的预览,一些文件的相关信息我们都已经可以拿到了,但是假如我想要上传的是一张图片,想要直接本地预览这张图片能不能直接在本地完成呢?答案是可以的,只需要你掌握FileReader这个对象即可

??FileReader对象一共有4个方法,其中3个可以读取文件,另一个用来中断读取。无论读取成功或失败,方法并不会返回读取结果,这一结果存储在result属性中。 4个方法分别是:

  • readAsBinaryString(file)?????将文件读取为二进制编码
  • readAsText(file,[encoding])???将文件读取为文本
  • readAsDataURL(file)???????将文件读取为DataURL
  • abort????????????中断读取操作

FileReader对象同样也有很多事件,分别是:

  • onabort????中断
  • onerror????出错
  • onloadstart??开始
  • onprogress??正在读取
  • onload????成功读取
  • onloadend??读取完成,无论成功失败

那我们在上面的事件方法基础上就可以实现关于本地预览图片的相关方法:

var reader = new FileReader();  //创建一个FileReader对象
reader.readAsDataURL(file);      //将文件以Data URL形式读入页面 ,并且将结果存在result属性中
reader.onload=function(e){      //当文件成功读取后
    var imgBox=document.getElementById("imgBox");
    imgBox.innerHTML=‘<img src="‘ + this.result +‘"  />‘;  //显示文件
}  

通过上面的方法就可以实现图片的本地预览了,当然上面那个方法还可以结合之前的files对象中的type,size等属性实现上传图片类型大小的限制。

关于HTML5的上传部分,实际上还有很多应用的地方,将会在以后的博客中告诉大家。

时间: 2024-12-06 06:57:42

HTML5关于上传API的一些使用(上)的相关文章

HTML5关于上传API的一些使用(中)

上一次写了关于HTML的上传API,XMLHttpRequest2.0的上传方式,以及HTML5中上传之前本地的预览,包括对于图片以及部分信息的预 览.这次我们就讲下HTML5中关于上传的一些各种个性化需求的处理,主要包括实时进度条,上传速度的实时显示等. 关于上传事件 首先要做到实时进度条这种需求,首先我们需要得到关于上传的各种事件,这些事件大部分都是在XMLHttpRequest这个对象下面: progress事件:上传进度事件. load事件:传输成功完成. abort事件:传输被用户取消

HTML5关于上传API的一些使用(下)

通过前面两篇的分享,我们已经搞定了单个文件的普通的上传,包括文件预览,图片预览,上传速度等前端界面的显示,这次我们来谈谈关于>XMLHttpRequest2.0在界面之后假如才用分片上传能做到一些什么功能 关于分片上传 为什么要使用分片上传? 考虑如下场景,假如用户需要在一个视频分享社区上传一部.avi的视频文件进行分享,大小在2G以上,这个时候用户假如在上传的过程当中,发生了宽带掉线,不小心关闭了浏览器等这种意外的事情,用户这个时候除了重传整个文件以外,没有其他更好的选择,可能用户就不会考虑再

腾讯云cos对象存储服务文件上传api就是一个大坑

一.介绍 对象存储服务(Cloud Object Service)是基于腾讯多年海量服务经验,对外提供的可靠.安全.易用的海量存储服务.提供多样化接入方式,以及全国部署的上传加速集群,可以无缝衔接CDN进行加速下载. 二.cos 文件上传api源码 /** * 单个文件上传,适用于小文件 * * @param bucketName * bucket名称 * @param remotePath * 远程文件路径 * @param localPath * 本地文件路径 * @return 服务器端返

html5大文件上传解决方案支持分片断点上传

核心原理: 该项目核心就是文件分块上传.前后端要高度配合,需要双方约定好一些数据,才能完成大文件分块,我们在项目中要重点解决的以下问题. * 如何分片: * 如何合成一个文件: * 中断了从哪个分片开始. 如何分,利用强大的js库,来减轻我们的工作,市场上已经能有关于大文件分块的轮子,虽然程序员的天性曾迫使我重新造轮子.但是因为时间的关系还有工作的关系,我只能罢休了.最后我选择了百度的WebUploader来实现前端所需. 如何合,在合之前,我们还得先解决一个问题,我们如何区分分块所属那个文件的

Flash上传组件之SWFUpload文件上传

一.什么是SWFUpload? SWFUpload是一个客户端文件上传工具,最初由Vinterwebb.se开发,它通过整合Flash与JavaScript技术为WEB开发者提供了一个具有丰富功能继而超越传统<input type="file" />标签的文件上传模式. 目前此项目放在:https://code.google.com/p/swfupload/ 对应的中文API:http://leeon.me/upload/other/swfupload.html 由于SWF

文件上传表单 上传文件的细节 文件上传下载和数据库结合

1 文件上传表单   1)上传文件的本质是文本复制的过程   2)技术层面,在Java中一定会用到IO操作,主要以二进制方式读写   3)传统方式下,对于上传文件字段不同的浏览器有着不同的解析方式,例如:     IE6:upfile=c:\aa\bb\a.JPG     非IE6: upfile=a.JPG   4)可以将form以MIME协议的方式将上传文件传递到服务端,服务端以二进制流的方式读写     代码:客户端form enctype="multipart/form-data&quo

文件上传三:base64编码上传

介绍三种上传方式: 文件上传一:伪刷新上传 文件上传二:FormData上传 文件上传三:base64编码上传 Flash的方式也玩过,不喜欢不拿来说了. 优点: 1.浏览器可以马上展示图像,不需要先上传到服务端,减少服务端的垃圾图像 2.前端可以压缩.处理后上传到服务端,减少传输过程中的等待时间和服务器压力 缺点: 1.生成编码后保存成图片,倘若不做处理,会比原来的图片容量大,具体原因,搜索关键词:Base64编码为什么会使数据量变大 2.图片越大生成的编码越多,编码越多开发者工具中查看它时卡

.net 实现上传文件分割,断点续传上传文件

一 介绍 断点续传搜索大部分都是下载的断点续传,涉及到HTTP协议1.1的Range和Content-Range头. 来个简单的介绍 所谓断点续传,也就是要从文件已经下载的地方开始继续下载.在以前版本的 HTTP 协议是不支持断点的,HTTP/1.1 开始就支持了.一般断点下载时才用到 Range 和 Content-Range 实体头. Range 用于请求头中,指定第一个字节的位置和最后一个字节的位置,一般格式: Range:(unit=first byte pos)-[last byte

web大文件上传解决方案支持分片断点上传

一. 功能性需求与非功能性需求 要求操作便利,一次选择多个文件和文件夹进行上传:支持PC端全平台操作系统,Windows,Linux,Mac 支持文件和文件夹的批量下载,断点续传.刷新页面后继续传输.关闭浏览器后保留进度信息. 支持文件夹批量上传下载,服务器端保留文件夹层级结构,服务器端文件夹层级结构与本地相同. 支持大文件批量上传(20G)和下载,同时需要保证上传期间用户电脑不出现卡死等体验:支持文件夹上传,文件夹中的文件数量达到1万个以上,且包含层级结构. 支持断点续传,关闭浏览器或刷新浏览