案例背景:同时上传两个不同name文件,使用ajax方式,上传后进行状态处理(函数回调)。
如果不考虑上传后的状态,或者仅仅提示上传结果。那么可以直接只用form 表单 submit方式。同样可以实现多个文件上传。
如果使用同name上传,那么input标签有multiple属性,可以上传多个文件。表单如下:
<form action="upload.do" method="post" enctype="multipart/form-data">
<input type="text" name="desc" value=""/><br/>
<input type="file" name="files" multiple/><br/>
<input type="submit" value="Submit"/>
</form>
如果不使用multiple属性,那么就需要写多个文件域,这显然是不可取的。表单如下:
<form action="upload.do" method="post" enctype="multipart/form-data">
<input type="text" name="desc" value=""/><br/>
<input type="file" name="files" /><br/>
<input type="file" name="files" /><br/>
<input type="submit" value="Submit"/>
</form>
后台接收方法如下(使用数组接收):
@RequestMapping(value="/upload.do")
public String fileUpload(@RequestParam("files") MultipartFile[] files,HttpServletRequest request) {
//...
}
如上所述,submit方式的弊端在于文件上传中,无法有效捕获文件上传状态及进行的后续处理!
故,采用ajax方式(你可以使用ajax upload 插件),本文使用formdata方式。
【FormData】
通过FormData对象可以组装一组用 XMLHttpRequest发送请求的键/值对。它可以更灵活方便的发送表单数据,因为可以独立于表单使用。
如果你把表单的编码类型设置为multipart/form-data ,则通过FormData传输的数据格式和表单通过submit() 方法传输的数据格式相同
即,此时使用FormData对象传送的数据不会发送格式改变!!!
表单示例如下:
<form id="myform" name="myform" action="<%=basePath%>data/saveDataImport.do" class="layui-form" method="post" enctype="multipart/form-data" >
<div class="layui-form-item">
<label class="layui-form-label">请选择POS表:</label>
<div class="layui-input-block">
<input id="pos" type="file" name="pos" >
</div>
</div>
<div class="layui-form-item" >
<label class="layui-form-label">请选择商品表:</label>
<div class="layui-input-block">
<input id="goods" type="file" name="goods" >
</div>
</div>
<div class="layui-form-item" style="margin-top: 40px;">
<div class="layui-input-block">
<button id = "upload" class="layui-btn" type="button">确定</button>
<button name="cancel" type="button" class="layui-btn" onclick="f_cancel();">取消</button>
</div>
</div>
</form>
构建FormData对象:
下面两种正确方式:
var posFormData = new FormData($("#myform")[0]);
or
var posFormData = new FormData($("form")[0]);
参数对比如下图:
【FormData】如下图:
JS如下:
$(function(){
$("#upload").click(function(){
var posFormData = new FormData($("#myform")[0]);
$.ajax({
url: url,
type: 'POST',
data: posFormData,
contentType: false, //禁止设置请求类型
processData: false, //禁止jquery对DAta数据的处理,默认会处理
beforeSend: function(){
//返回的参数item,即为当前的input DOM对象
index = layer.load(1,{shade: [0.3,'grey']});
},
success: function(data) {
if (typeof data != "object") {
jsonReturn = eval("("+data+")");
}else{
jsonReturn=data;
}
//关闭遮罩层
layer.close(index);
if(jsonReturn.code == "true"){
layer.msg(jsonReturn.message,{icon:1,time: 1000},function(){
f_cancel();
top.f_getframe("goods_index_do").f_goods_sale_query();
});
}else{
layer.msg(jsonReturn.message,{icon: 7,time: 2000});
}
}
});
});
});
上传参数如下图:
使用submit方式上传文件参数如下图:
对比发现,二者数据格式完全一致!!!
后台接收方法如下:
@RequestMapping(value="saveDataImport",produces="application/json;charset=utf-8" )
@ResponseBody
public String saveDataImport(@RequestParam(value="pos",required=false)MultipartFile posFile,@RequestParam(value="goods",required=false)MultipartFile goodsFile){
//...
}