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 +'" alt="" />'; //显示文件
}

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

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

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

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

    上一次写了关于HTML的上传API,XMLHttpRequest2.0的上传方式,以及HTML5中上传之前本地的预览,包括对于图片以及部分信息的预 览.这次我们就讲下HTML5中关于上传的一些各种个性 ...

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

    通过前面两篇的分享,我们已经搞定了单个文件的普通的上传,包括文件预览,图片预览,上传速度等前端界面的显示,这次我们来谈谈关于>XMLHttpRequest2.0在界面之后假如才用分片上传能做到一 ...

  3. 优酷视频上传api及demo代码

    1,优酷正常上传流程: 1). create:连接开放平台上传接口服务器,服务器端会返回upload_token以及upload_server_uri.2). create_file:连接上传服务器( ...

  4. php+html5实现无刷新上传,大文件分片上传,断点续传

    核心原理: 该项目核心就是文件分块上传.前后端要高度配合,需要双方约定好一些数据,才能完成大文件分块,我们在项目中要重点解决的以下问题. * 如何分片: * 如何合成一个文件: * 中断了从哪个分片开 ...

  5. Flash上传组件之SWFUpload文件上传

    一.什么是SWFUpload? SWFUpload是一个客户端文件上传工具,最初由Vinterwebb.se开发,它通过整合Flash与JavaScript技术为WEB开发者提供了一个具有丰富功能继而 ...

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

    一 介绍 断点续传搜索大部分都是下载的断点续传,涉及到HTTP协议1.1的Range和Content-Range头. 来个简单的介绍 所谓断点续传,也就是要从文件已经下载的地方开始继续下载.在以前版本 ...

  7. Spring Boot2(十四):单文件上传/下载,文件批量上传

    文件上传和下载在项目中经常用到,这里主要学习SpringBoot完成单个文件上传/下载,批量文件上传的场景应用.结合mysql数据库.jpa数据层操作.thymeleaf页面模板. 一.准备 添加ma ...

  8. 文件上传三:base64编码上传

    介绍三种上传方式: 文件上传一:伪刷新上传 文件上传二:FormData上传 文件上传三:base64编码上传 Flash的方式也玩过,现在不推荐用了. 优点: 1.浏览器可以马上展示图像,不需要先上 ...

  9. 微信小程序语音(A)发给别人(B),也能播放,是需要先把语音上传到自己的服务器上才可以

    小程序语音(A)发给别人(B),也能播放,是需要先把语音上传到自己的服务器上才可以. https://developers.weixin.qq.com/miniprogram/dev/api/medi ...

随机推荐

  1. wifidog 移植到MIPS平台

    使用的是一款Broadcom的芯片,现在上面运行wifidog实现认证上网的功能.由于不是openwrt平台,所以就没了make menuconfig 勾选就能自动编译到版本中的.所以想使用交叉编译的 ...

  2. C#应用视频教程3.2 Halcon软件测试

    Halcon是图像处理比较牛逼的一个软件(德国人的东西,做的非常强大,里面集成的算法很多,可能你一辈子研究这个也做不过他),然而牛逼归牛逼,康耐视,基恩士也很牛逼,但是日本人的东西一般太过封闭,屌丝用 ...

  3. 异步任务,HttpContext.Current为null解决办法

    最近在开发一个后台管理系统项目,为了提高登录的速度,就把记录登录日志放到一个异步任务里面. Action taskAction = () => { SaveLog(); }; Task task ...

  4. Asp.Net MVC4开发二: Entity Framework在Asp.Net MVC4中的应用

    ORM作为一种数据库訪问机制已广泛地应用于各种项目其中,在.Net开发中,应用比較广泛的ORM框架大致有以下几个: 官方支持的有:Linq to SQL.Entity Framework.三方的有:N ...

  5. Oracle 正则 整词匹配 \b 不行

    在oracle中用整词匹配\b来包裹想要匹配的词并不可行, 正确的做法应该是这样: FROM DUAL WHERE REGEXP_LIKE('1 2 3 14','(^|\s|\W)3($|\s|\W ...

  6. jquery 常用api 小结2

    *一)jQuery常用方法API实战 (1)DOM简述与分类 A)DOM是一种标准,它独立于平台,语言,浏览器. B)如果项目中,你完全按照DOM标准写代码,你就能在各大主流的浏览器中操作标准控件. ...

  7. ML 与 DM 工具 Weka 的使用

    1.关于Weka Weka 的全名是怀卡托智能分析环境(Waikato Environment for Knowledge Analysis),是一款免费的.非商业化(与之对应的是SPSS公司商业数据 ...

  8. C#指南,重温基础,展望远方!(12)C#特性

    C# 程序中的类型.成员和其他实体支持使用修饰符来控制其行为的某些方面. 例如,方法的可访问性是由 public.protected.internal 和 private 修饰符控制. C# 整合了这 ...

  9. c#+mysql 中文乱码

    c#+mysql 中文乱码 遇到一个奇怪的问题,C#读取mysql中文正常,写入时发生乱码 网上查阅原因,发现如下信息 ---------------------------------------- ...

  10. AHK GUI开发示例

    GUI.AHK Gui, Add, Text, gAllSearchA W120, 搜索引擎类: Gui, Add, Checkbox, gMySubroutine Checked HwndMyEdi ...