js使用formData实现批量上传
最近项目需要批量上传附件,查了下资料,网上很多但看着一脸懵,只贴部分代码,介绍也不详细,这里记录一下自己的采坑与多种实现,以免以后忘记。
这里先介绍下formdata对象,以下内容摘自地址
xmlhttprequest level 2添加了一个新的接口formdata.利用formdata对象,我们可以通过javascript用一些键值对来模拟一系列表单控件,我们还可以使用xmlhttprequest的send()方法来异步的提交这个"表单".比起普通的ajax,使用formdata的最大优点就是我们可以异步上传一个二进制文件.
在我的里就已经实现里单文件上传,并且实现了自定义input样式;如果构造formdata对象是传入表单js对象,formdata会自动注入表单里的值;如果是new一个空对象,然后手动append的表单类型为file时要注意:这里append进去的是file对象,而不是filelist对象
先看一下大概效果:
controller有两种方法:三种方式调的都是用一个接口
/** * 批量上传 */ @postmapping("upload") public resultmodel<list<attachmentvo>> upload(httpservletrequest request, @requestparam("applyid") string applyid){ list<multipartfile> multipartfilelist = ((multiparthttpservletrequest) request).getfiles("attachment"); system.out.println(multipartfilelist.size()); system.out.println(applyid); return null; } /** * 批量上传2 (推荐使用) */ @postmapping("upload2") public resultmodel<list<attachmentvo>> upload2(multipartfile[] attachment,@requestparam("applyid") string applyid){ system.out.println(attachment.length); system.out.println(applyid); return null; }
方式1
点击add,追加一个input,点击delete,删除一个input,点击叉号也可以删除对应的input,需要单独为每个input选择文件
效果
html
<form id="attachments" enctype="multipart/form-data" class="form-horizontal nice-validator n-yellow" novalidate="novalidate"> <div class='form-body'> <div class='form-group'> <label class="control-label col-md-1">附件管理:</label> <div class="col-md-4"> <button id="attachmentaddbtn" type="button" class="btn btn-default">add attachment</button> <button id="attachmentdeletebtn" type="button" class="btn btn-default">delete attachment</button> <button id="attachmentuploadbtn" type="button" class="btn btn-default">upload</button> </div> </div> <div class='form-group'> <label class="control-label col-md-1">附件上传:</label> <div id="attachmentinputs" class="col-md-3"> </div> </div> </div> </form>
js
//attachment-remove $("#attachmentinputs").on("click", ".attachment-remove", function (even) { $(this).prev().remove();//删除上一个兄弟节点 $(this).remove();//删除自己 }); //add but $("#attachmentaddbtn").click(function (even) { //name值一样就可以 $("#attachmentinputs").append("<input name=\"attachment\" type=\"file\" class=\"form-control input-attachment\"/><i class=\"fa fa-times attachment-remove\"></i>"); }); //delete $("#attachmentdeletebtn").click(function (even) { var files = $("#attachmentinputs input[type='file']"); files.each(function (index, element) { //从最下面开始删除,至少保留一个 if (!(index === 0) && index === (files.length - 1)) { $(element).next().remove(); $(element).remove(); } }); }); //upload $("#attachmentuploadbtn").click(function (even) { //1、通过html表单创建formdata对象 自动注入 // var formdata = new formdata($("#attachments")[0]); //2、从零开始创建formdata对象 手动注入 var formdata = new formdata(); //注入 name=file var files = $("#attachmentinputs input[type='file']"); for (var i = 0; i < files.length; i++) { //注意:这里append进去的是file对象,而不是filelist对象 formdata.append("attachment", files[i].files[0]); } //注入name=text formdata.append("applyid", "123456"); console.log(formdata.getall("attachment")); //执行上传 $.ajax({ url: ctx + "/attachment/upload2", type: "post", data: formdata, processdata: false, contenttype: false, success: function (data) { }, error: function (e) { } }); }); //add one input $("#attachmentaddbtn").click();
方式2
第二种方式只有一个input,用的是multiple="multiple"属性,可以再弹窗里选择多个文件提交,如果再加工一下,也做成第三种一样,展示出文件名,同时可以删除对应的文件
效果
html
<form id="attachments2" enctype="multipart/form-data" class="form-horizontal" novalidate="novalidate"> <div class='form-body'> <div class='form-group'> <label class="control-label col-md-1">附件管理:</label> <div class="col-md-4"> <button id="attachmentuploadbtn2" type="button" class="btn btn-default">upload</button> </div> </div> <div class='form-group'> <label class="control-label col-md-1">附件上传:</label> <div id="attachmentinputs2" class="col-md-3"> <input name="attachment" type="file" class="form-control input-attachment" multiple="multiple"/> </div> </div> </div> </form>
js
//upload2 $("#attachmentuploadbtn2").click(function (even) { //1、通过html表单创建formdata对象 自动注入 // var formdata = new formdata($("#attachments2")[0]); //2、从零开始创建formdata对象 手动注入 var formdata = new formdata(); //注入 name=file var files = $("#attachmentinputs2 input[type='file']"); for (var i = 0; i < files[0].files.length; i++) { formdata.append("attachment", files[0].files[i]); } //注入name=text formdata.append("applyid", "123456"); console.log(formdata.getall("attachment")); //执行上传 $.ajax({ url: ctx + "/attachment/upload2", type: "post", data: formdata, processdata: false, contenttype: false, success: function (data) { }, error: function (e) { } }); });
方式3
定义了一个隐藏的input,并将select file按钮的click与input的click对等,点击按钮相当于点击input,弹出选择文件对话框,监听了input的change事件,将选择的file对象push到全局数组变量attachmentarray中,点击upload时再遍历注入到formdata中
效果
html
<form id="attachments3" enctype="multipart/form-data" class="form-horizontal" novalidate="novalidate"> <div class='form-body'> <div class='form-group'> <label class="control-label col-md-1">附件管理:</label> <div class="col-md-4"> <button id="selectfile" type="button" class="btn btn-default">select file</button> <button id="attachmentuploadbtn3" type="button" class="btn btn-default">upload</button> </div> </div> <div class='form-group'> <label class="control-label col-md-1">附件上传:</label> <input id="attachmentinputs3" type="file" style="display: none;"/> <div id="attachmenttext3" class="col-md-3"> </div> </div> </div> </form>
js
//存放file对象 var attachmentarray = []; //attachment-remove $("#attachmenttext3").on("click", ".attachment-remove", function (even) { //删除attachmentarray数据 attachmentarray.splice($(this).data("index"), 1); //删除html对象 $(this).prev().prev().remove(); $(this).prev().remove(); $(this).remove(); }); //select file $("#selectfile").click(function (even) { // 获取input $("#attachmentinputs3").click(); }); //input change $("#attachmentinputs3").change(function (even) { // 获取input var filename = $(this).val(); var file = $(this)[0].files[0]; //是否选择了文件 if (filename) { attachmentarray.push(file); $("#attachmenttext3").append("<div><p class='attachment-text-p'>" + filename + "</p><i data-index='" + (attachmentarray.length - 1) + "' class=\"fa fa-times attachment-remove\"></i></div>") } }); //upload3 $("#attachmentuploadbtn3").click(function (even) { //这里只能手动注入 var formdata = new formdata(); //遍历数据,手动注入formdata for (var i = 0; i < attachmentarray.length; i++) { formdata.append("attachment", attachmentarray[i]); } formdata.append("applyid", "123456"); console.log(formdata.getall("attachment")); //执行上传 $.ajax({ url: ctx + "/attachment/upload", type: "post", data: formdata, processdata: false, contenttype: false, success: function (data) { }, error: function (e) { } }); });
最后看一下file数据、请求头、还有振奋人心的后台成功接参图
file数据
请求头
成功接参
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。