通过传统的form表单提交的方式上传文件

通过传统的form表单提交的方式上传文件

<form id= "uploadForm" action= "http://localhost:8080/cfJAX_RS/rest/file/upload" method= "post" enctype ="multipart/form-data">    
     <h1 >测试通过Rest接口上传文件 </h1>    
     <p >指定文件名: <input type ="text" name="filename" /></p>    
     <p >上传文件: <input type ="file" name="file" /></p>    
     <p >关键字1: <input type ="text" name="keyword" /></p>    
     <p >关键字2: <input type ="text" name="keyword" /></p>    
     <p >关键字3: <input type ="text" name="keyword" /></p>    
     <input type ="submit" value="上传"/>    
</form> 
不过 传统的 form 表单提交会导致页面刷新, 但是在有些情况下,我们不希望页面被刷新,这种时候我们都是使用Ajax的方式进行请求的。

Ajax的方式进行请求

    $.ajax({    
         url : "http://localhost:8080/STS/rest/user",    
         type : "POST",    
         data : $( '#postForm').serialize(),    
         success : function(data) {    
              $( '#serverResponse').html(data);    
         },    
         error : function(data) {    
              $( '#serverResponse').html(data.status + " : " + data.statusText + " : " + data.responseText);    
         }    
    });   
通常我们提交(使用submit button)时,会把form中的所有表格元素的name与value组成一个queryString,提交到后台。这用jQuery的方法来说,就是serialize。

通过 $( '#postForm' ).serialize() 可以对form表单进行序列化,从而将form表单中的所有参数传递到服务端。
但是上述方式,只能传递一般的参数, 上传文件的文件流是无法被序列化并传递的。
不过如今主流浏览器都开始支持一个叫做FormData的对象,有了这个FormData,我们就可以轻松地使用Ajax方式进行文件 上传 了。

关于FormData及其用法


FormData是什么呢?我们来看看Mozilla上的介绍。

XMLHttpRequest Level 2添加了一个新的接口 FormData.利用 FormData对象,我们可以通过JavaScript用一些键值对来模拟一系列表单控件,我们还可以使用XMLHttpRequest的 send()方法来异步的提交这个"表单".比起普通的ajax,使用 FormData的最大优点就是我们可以异步上传一个二进制文件. 
  所有主流浏览器的较新版本都已经支持这个对象了,比如Chrome 7+、Firefox 4+、IE 10+、Opera 12+、Safari 5+。

Constructor


FormData()

var formdata = new FormData();
想得到一个FormData对象:

W3c草案提供了三种方案来获取或修改FormData。

方案1:创建一个空的FormData对象,然后再用append方法逐个添加键值对:

var formdata = new FormData();
formdata.append("name", "呵呵");
formdata.append("url", "http://www.baidu.com/");
方案2:取得form元素对象,将它作为参数传入FormData对象中!

var formdata = new FormData();
formdata.append("name", "呵呵");
formdata.append("url", "http://www.baidu.com/");

方案3:利用form元素对象的getFormData方法生成它!
var formobj =  document.getElementById("form");
var formdata = formobj.getFormData()

Method

FormData.append

本方法用于向已存在的键添加新的值,如该键不存在,新建之。

语法
formData.append(name, value);
formData.append(name, value, filename);
注: 通过 FormData.append()方法赋给字段的值若是数字会被自动转换为字符(字段的值可以是一个Blob对象,一个File对象,或者一个字符串,剩下其他类型的值都会被自动转换成字符串).
参数解释
  • name
    键 (key), 对应表单域
  • value
    表单域的值
  • filename (optional)
    The filename reported to the server (a USVString), when a Blob or File is passed as the second parameter. The default filename for Blob objects is "blob".

FormData.delete

将一对键和值从 FormData 对象中删除。

formData.delete(username);

FormData.get

返回给定键的第一个值

formData.append('username', 'Justin');
formData.append('username', 'Chris');
formData.get(username);    // "Justin"

FormData.getAll

返回给定键的所有值

formData.append('username', 'Justin');
formData.append('username', 'Chris');
formData.getAll(username);    // ["Justin", "Chris"]

FormData.has

检查是否包含给定键,返回 true 或 false

formData.has(username);

FormData.set

设置给定键的值

formData.set(name, value);
formData.set(name, value, filename);

浏览器兼容情况

来自 MDN

Desktop

Feature Chrome Firfox(Gecko) Intenet Explorer Opera Safari
Basic support7+4.0(2.0)10+12+5+
append with filename(Yes)22.0(22.0)???
delete, get, getAll, has, setBehind FlagNot supportedNot supported(Yes)Not supported

Mobile

Feature Android Chrome Android Firfox Mobile (Gecko) Firfox OS (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support3.0?4.0(2.0)1.0.1?12+?
append with filename??22.0(22.0)1.2???
delete, get, getAll, has, set(Yes)(Yes)Not supportedNot supportedNot supported(Yes)Not supported


Ajax通过FormData上传文件

1.使用<form>表单初始化FormData对象方式上传文件HTML代码

<form id="uploadForm" enctype="multipart/form-data">
    <input id="file" type="file" name="file"/>
    <button id="upload" type="button">upload</button>
</form>


javascript代码

$.ajax({
    url: '/upload',
    type: 'POST',
    cache: false,
    data: new FormData($('#uploadForm')[0]),
    processData: false,
    contentType: false
}).done(function(res) {
}).fail(function(res) {});


这里要注意几点:

  • processData设置为false。因为data值是FormData对象,不需要对数据做处理。
  • <form>标签添加enctype="multipart/form-data"属性。
  • cache设置为false,上传文件不需要缓存。
  • contentType设置为false,不设置contentType值,因为是由<form>表单构造的FormData对象,且已经声明了属性enctype="multipart/form-data",所以这里设置为false。

上传后,服务器端代码需要使用从查询参数名为file获取文件输入流对象,因为<input>中声明的是name="file"

如果不是用<form>表单构造FormData对象又该怎么做呢?

2.使用FormData对象添加字段方式上传文件

HTML代码

<div id="uploadForm">
    <input id="file" type="file"/>
    <button id="upload" type="button">upload</button>
</div>

这里没有<form>标签,也没有enctype="multipart/form-data"属性。


javascript代码

var formData = new FormData();
formData.append('file', $('#file')[0].files[0]);
$.ajax({
    url: '/upload',
    type: 'POST',
    cache: false,
    data: formData,
    processData: false,
    contentType: false
}).done(function(res) {
}).fail(function(res) {});

这里有几处不一样:

  • append()的第二个参数应是文件对象,即$('#file')[0].files[0]
  • contentType也要设置为‘false’。

从代码$('#file')[0].files[0]中可以看到一个<input type="file">标签能够上传多个文件,
只需要在<input type="file">里添加multiplemultiple="multiple"属性。

3.服务器端读文件

Servlet 3.0 开始,可以通过 request.getPart() 或 request.getPars() 两个接口获取上传的文件

转载文章:

http://www.jianshu.com/p/46e6e03a0d53

https://segmentfault.com/a/1190000002875573

http://my.oschina.net/u/1866405/blog/335987

http://yunzhu.iteye.com/blog/2177923

https://developer.mozilla.org/zh-CN/docs/Web/Guide/Using_FormData_Objects

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值