XMLHttpRequest 是一个浏览器接口,通过它,我们可以使得 Javascript 进行 HTTP (S) 通信。XMLHttpRequest 在现在浏览器中是一种常用的前后台交互数据的方式。2008年 2 月,XMLHttpRequest Level 2 草案提出来了,相对于上一代,它有一些新的特性,其中 FormData 就是 XMLHttpRequest Level 2 新增的一个对象,利用它来提交表单、模拟表单提交,当然最大的优势就是可以上传二进制文件。下面就具体介绍一下如何利用 FormData 来上传文件。

FormData 上传文件实例

首先看一下formData的基本用法:FormData对象,可以把所有表单元素的name与value组成一个queryString,提交到后台。只需要把 form 表单作为参数传入 FormData 构造函数即可:

  1. var form = document.getElementById("form1");
  2. var fd = new FormData(form);
  • 1
  • 2

这样就可以直接通过ajax 的 send() 方法将 fd 发送到后台。

以下创建了一个表单 form,表单中除了普通的数据外,还有文件上传,我们直接将 form对象作为参数传入FormData对象:

  1. <form name="form1" id="form1">
  2. <p>name:<input type="text" name="name" /></p>
  3. <p>gender:<input type="radio" name="gender" value="1" />male <input type="radio" name="gender" value="2" />female</p>
  4. <p>stu-number:<input type="text" name="number" /></p>
  5. <p>photo:<input type="file" name="photo" id="photo"></p>
  6. <p><input type="button" name="b1" value="submit" onclick="fsubmit()" /></p>
  7. </form>
  8. <div id="result"></div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

上述代码创建一个form,简单的填写一些信息,以及选择一张图片作为头像,设置一个div来存放返回的结果。

为了简便,我们还是采用jquery封装的ajax来向后台传输数据:

  1. function fsubmit() {
  2. var form=document.getElementById("form1");
  3. var fd =new FormData(form);
  4. $.ajax({
  5. url: "server.php",
  6. type: "POST",
  7. data: fd,
  8. processData: false, // 告诉jQuery不要去处理发送的数据
  9. contentType: false, // 告诉jQuery不要去设置Content-Type请求头
  10. success: function(response,status,xhr){
  11. console.log(xhr);
  12. var json=$.parseJSON(response);
  13. var result = '';
  14. result +="个人信息:<br/>name:"+json['name']+"<br/>gender:"+json['gender']+"<br/>number:"+json['number'];
  15. result += '<br/>头像:<img src="' + json['photo'] + '" height="100" style="border-radius: 50%;" />';
  16. $('#result').html(result);
  17. }
  18. });
  19. return false;
  20. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

上述代码中的 server.php 是服务器端的文件,接收ajax请求,并将接收结果返回,具体代码如下:

  1. <?php
  2. $name = isset($_POST['name'])? $_POST['name'] : '';
  3. $gender = isset($_POST['gender'])? $_POST['gender'] : '';
  4. $number = isset($_POST['number'])? $_POST['number'] : '';
  5. $filename = time().substr($_FILES['photo']['name'], strrpos($_FILES['photo']['name'],'.'));
  6. $response = array();
  7. if(move_uploaded_file($_FILES['photo']['tmp_name'], $filename)){
  8. $response['isSuccess'] = true;
  9. $response['name'] = $name;
  10. $response['gender'] = $gender;
  11. $response['number'] = $number;
  12. $response['photo'] = $filename;
  13. }else{
  14. $response['isSuccess'] = false;
  15. }
  16. echo json_encode($response);
  17. ?>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

填写好信息后,点击 submit,页面中能得到以下效果,去服务器端对应的文件夹下也能发现上传的图片。

如果你是原生 JavaScript 爱好者,当然一样能实现以上功能,下面是简单的JavaScript实现代码:

  1. function fsubmit() {
  2. var form=document.getElementById("form1");
  3. var formData=new FormData(form);
  4. alert(formData.name);
  5. var oReq = new XMLHttpRequest();
  6. oReq.onreadystatechange=function(){
  7. if(oReq.readyState==4){
  8. if(oReq.status==200){
  9. console.log(typeof oReq.responseText);
  10. var json=JSON.parse(oReq.responseText);
  11. var result = '';
  12. result +="个人信息:<br/>name:"+json['name']+"<br/>gender:"+json['gender']+"<br/>number:"+json['number'];
  13. result += '<br/>头像:<img src="' + json['photo'] + '" height="50" style="border-radius: 50%;" />';
  14. $('#result').html(result);
  15. }
  16. }
  17. };
  18. oReq.open("POST", "server.php");
  19. oReq.send(formData);
  20. return false;
  21. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

FormData 对象方法介绍

FormData 除了上面的创建新对象时直接将 form 作为参数传入外,还有其他的功能。网上大部分关于 FormData 介绍的文章都只提到了append()方法,那么FormData 对象到底有些什么方法呢?我们console 一下就知道:

console 之后我们有重大的发现,FormData 对象竟然有这么方法,所以还是自己测试才能发现真相,下面就对这些方法一一进行讲解:

1、append()

append()方法用于向 FormData 对象中添加键值对:

  1. fd.append('key1',"value1");
  2. fd.append('key2',"value2");
  • 1
  • 2

fd是 FormData 对象,可以新建的空的对象,也可以是已经包含 form 表单或其他键值对。

2、set()

设置对应的键 key 对应的值 value(s)

  1. fd.set('key1',"value1");
  2. fd.set('key2',"value2");
  • 1
  • 2

看起来跟append() 方法有点类似,这两者的区别就是,当指定的 key 值存在时,append()方法是将新增的添加的所以的键值对最后,而set()方法将会覆盖前面的设置的键值对。还是通过实例来对比,我们在前面的 form 的基础上 append() 或 set() 新的键值对:

  1. fd.append('name',"will");
  • 1

有两个key为name的键值对: 

  1. fd.set('name',"will");
  • 1

只有一个key为name的键值对: 

以上就是 append() 和 set() 的区别。如果设置的key值不存在,那么两者的效果是一样的。

3、delete()

接收一个参数,表示你要删除的 key 值的名字,如果有多个相同 key 值,会一并删除:

  1. fd.append('name','will');
  2. fd.delete('name');
  • 1
  • 2

form 中的 name 信息以及通过append() 新增的name 的信息都被删除了。

4、get() 和 getAll()

接收一个参数,表示需要查找的 key 的名称,返回第一个该 key 对应的 value 值。如果有多个相同的 key, 而且要返回所有的这个 key 对应的 value 值。

同样以上面的 form 表单为基础:

  1. fd.append('name','will');
  2. console.log(fd.get('name')); // sean
  • 1
  • 2
  1. fd.append('name','will');
  2. console.log(fd.getAll('name')); // ["sean", "will"]
  • 1
  • 2

5、has()

该方法也接收一个参数,同样是 key 的名称,返回一个Boolean 值, 用来判断FormData 对象是否含有该 key。以上面的form为例:

  1. console.log(fd.has('name')); // true
  2. console.log(fd.has('Name')); // false
  • 1
  • 2

6、keys()

该方法不需要接收参数,返回一个迭代器,通过这个迭代器,我们可以遍历FormData 对象中所有的 key。以上面的form为例:

  1. for (var key of fd.keys()) {
  2. console.log(key);
  3. }
  • 1
  • 2
  • 3

结果为:

  1. name
  2. gender
  3. number
  4. photo
  • 1
  • 2
  • 3
  • 4

7、values()

有遍历 key 的迭代,当然也就少不了遍历 value 的迭代器了。values()就是遍历value 的迭代器,用法与 keys() 类似:

  1. for (var value of fd.values()) {
  2. console.log(value);
  3. }
  • 1
  • 2
  • 3

结果:

8、entries()

有遍历 key 的迭代器,也有遍历 value 的迭代器,为何不搞一个两者一起的呢!entries()就是返回一个包含键值对的迭代器:

  1. for(var pair of fd.entries()) {
  2. console.log(pair[0]+ ', '+ pair[1]);
  3. }
  • 1
  • 2
  • 3

结果:

FormData兼容性问题

由于 FormData 是 XMLHttpRequest Level 2 新增的接口,现在 低于IE10 的IE浏览器不支持 FormData ,至于 上面介绍的 FormData 对象的方法经过测试,在 IE 浏览器中都不支持,具体的各大浏览器的支持情况可以参照下图:

 

[转] HTML5 FormData 方法介绍以及实现文件上传的更多相关文章

  1. HTML5 FormData 方法介绍以及实现文件上传

    XMLHttpRequest 是一个浏览器接口,通过它,我们可以使得 Javascript 进行 HTTP (S) 通信.XMLHttpRequest 在现在浏览器中是一种常用的前后台交互数据的方式. ...

  2. Html5+NodeJS——拖拽多个文件上传到服务器

    实现多文件拖拽上传的简易Node项目,可以在github上下载,你可以先下载下来:https://github.com/Johnharvy/upLoadFiles/. 解开下载下的zip格式包,建议用 ...

  3. HTML5 + AJAX ( 原生JavaScript ) 异步多文件上传

    这是在上篇 HTML5 + AJAX ( jQuery版本 ) 文件上传带进度条 的修改版本.后台代码不变就可以接着使用,但是脚本不再使用jQuery了,改为原生的 JavaScript 代码,所以我 ...

  4. html5拖拽事件 xhr2 实现文件上传 含进度条

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  5. HTML5 FormData方法介绍

    详细见链接 转载说明:转自CSDN上“诗渊”的博客

  6. Java java httpclient4.5 进行http,https通过SSL安全验证跳过,封装接口请求 get,post(formdata,json)封装,文件上传下载

    package api; import java.util.*; import java.net.URI; import org.apache.http.Consts; import org.apac ...

  7. Java Web使用Html5 FormData实现多文件上传

    前一阵子,迭代一个线上的项目,其中有一个图片上传的功能,之前用的ajaxfileupload.js来实现上传的,不过由于ajaxfileupload.js,默认是单文件上传(虽然可以通过修改源码的方法 ...

  8. PHP实现多文件上传的一些简单方法

    下面我们就通过具体的代码示例,为大家介绍PHP实现多文件上传的一些简单方法. 第一种方法:利用单个文件上传方法 一段简单的form表单代码如下: <!DOCTYPE html> <h ...

  9. PHP设置图片文件上传大小的具体实现方法

    PHP默认的上传限定是最大2M,想上传超过此设定的文件,需要调整PHP.apache等的一些参数 我们简要介绍一下PHP文件上传涉及到的一些参数: •file_uploads :是否允许通过HTTP上 ...

随机推荐

  1. Spring 学习04

    一.上节内容回顾 1 基于aspectj的注解aop操作 2 spring的jdbcTemplate操作 (1)实现crud操作 - 添加.修改.删除update方法 - 查询 -- 查询某个值 qu ...

  2. 【原创】angularjs1.3.0源码解析之执行流程

    Angular执行流程 前言 发现最近angularjs在我厂的应用变得很广泛,下周刚好也有个angular项目要着手开始做,所以先做了下功课,从源代码开始入手会更深刻点,可能讲的没那么细,侧重点在于 ...

  3. JDBC preparedStatement分页和统计,批处理和事务

    一个类:DriverManager 四个接口:Connection.PreparedStatement .ResultSet.Statement 连接不上数据库出错的原因 1.数据库监听服务的配置不正 ...

  4. Java——分页 Servlet + Jsp+Jdbc 有点瑕疵

    1.创建数据库,插入多条数据 2.java连接DB 3.Person类: package com.phome.po; public class Person { private int id; pri ...

  5. OpenCV在字符提取中进行的预处理(转)

    OCR简介熟悉OCR的人都了解,OCR大致分为两个部分: -文字提取text extractor -文字识别text recognition 其中,第一部分是属于图像处理部分,涉及到图像分割的知识,而 ...

  6. Regex实例

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  7. MySQL - 日常操作二 备份还原

    登录mysql的命令 # 格式: mysql -h 主机地址 -u 用户名 -p 用户密码 mysql -h 110. -P3306 -uroot -p mysql -uroot -p -S /dat ...

  8. jdk学习之如何调试jdk

    自从sun被oracle收购后,在oracle下载的jdk使用F5进入调试jdk的方法就不行了,这对于想看jdk的源码的小伙伴是一个暴击(oracle在编译rt.jar时去除了调试信息): 这不得不鼻 ...

  9. luogu P4160 [SCOI2009]生日快乐

    传送门 考虑因为每个人的蛋糕体积要相等,如果切了一刀,那么要使得分当前蛋糕的人根据分成的两部分蛋糕的体积分成两部分人,所以假设当前有n人,切的这一刀要是在x或y的\(\frac{k}{n}(k\in ...

  10. Java导出List集合到txt文件中——(四)

    有时候,需要将数据以一定格式导出到txt文件中.利用Java的IO可以轻松的导出数据到txt中. package Action.txt; import java.io.BufferedWriter; ...