js使用formData实现批量上传


Posted in Javascript onMarch 27, 2020

最近项目需要批量上传附件,查了下资料,网上很多但看着一脸懵,只贴部分代码,介绍也不详细,这里记录一下自己的采坑与多种实现,以免以后忘记。

这里先介绍下FormData对象,以下内容摘自地址

XMLHttpRequest Level 2添加了一个新的接口FormData.利用FormData对象,我们可以通过JavaScript用一些键值对来模拟一系列表单控件,我们还可以使用XMLHttpRequest的send()方法来异步的提交这个"表单".比起普通的ajax,使用FormData的最大优点就是我们可以异步上传一个二进制文件.

在我的自定义input文件上传样式里就已经实现里单文件上传,并且实现了自定义input样式;如果构造FormData对象是传入表单js对象,formData会自动注入表单里的值;如果是new一个空对象,然后手动append的表单类型为file时要注意:这里append进去的是File对象,而不是FileList对象

先看一下大概效果:

js使用formData实现批量上传

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选择文件

效果

js使用formData实现批量上传

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"属性,可以再弹窗里选择多个文件提交,如果再加工一下,也做成第三种一样,展示出文件名,同时可以删除对应的文件

效果

js使用formData实现批量上传

js使用formData实现批量上传

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中

效果

js使用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数据

js使用formData实现批量上传

请求头

js使用formData实现批量上传

成功接参

js使用formData实现批量上传

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
IE8 兼容性问题(属性名区分大小写)
Jun 04 Javascript
jquery原创弹出层折叠效果点击折叠弹出一个层
Mar 12 Javascript
jQuery队列操作方法实例
Jun 11 Javascript
理解JS事件循环
Jan 07 Javascript
JQuery插件Marquee.js实现无缝滚动效果
Apr 26 Javascript
javascript实现简单的on事件绑定
Aug 23 Javascript
JavaScript中apply方法的应用技巧小结
Sep 29 Javascript
基于JS实现网页中的选项卡(两种方法)
Jun 16 Javascript
angular第三方包开发整理(小结)
Apr 19 Javascript
Vue唯一可以更改vuex实例中state数据状态的属性对象Mutation的讲解
Jan 18 Javascript
从0到1搭建element后台框架优化篇(打包优化)
May 12 Javascript
layui弹出框Tab选项卡的示例代码
Sep 04 Javascript
详解webpack打包时排除其中一个css、js文件或单独打包一个css、js文件(两种方法)
Oct 26 #Javascript
js自定义input文件上传样式
Oct 26 #Javascript
解决axios会发送两次请求,有个OPTIONS请求的问题
Oct 25 #Javascript
在Vue中使用axios请求拦截的实现方法
Oct 25 #Javascript
webpack4+react多页面架构的实现
Oct 25 #Javascript
浅谈让你的代码更简短,更整洁,更易读的ES6小技巧
Oct 25 #Javascript
代码整洁之道(重构)
Oct 25 #Javascript
You might like
虹吸式咖啡探讨–研磨
2021/03/03 冲泡冲煮
一个简单计数器的源代码
2006/10/09 PHP
PHP+JS无限级可伸缩菜单详解(简单易懂)
2007/01/02 PHP
php木马攻击防御之道
2008/03/24 PHP
JAVASCRIPT  THIS详解 面向对象
2009/03/25 Javascript
jQueryUI的Dialog的简单封装
2010/06/07 Javascript
面向对象的Javascript之三(封装和信息隐藏)
2012/01/27 Javascript
js查错流程归纳
2012/05/04 Javascript
jQuery 获取/设置/删除DOM元素的属性以a元素为例
2014/05/23 Javascript
JSON字符串和对象之间的转换详解
2015/05/26 Javascript
JavaScript数组去重的3种方法和代码实例
2015/07/01 Javascript
location.hash保存页面状态的技巧
2016/04/28 Javascript
基于JavaScript代码实现自动生成表格
2016/06/15 Javascript
扩展Bootstrap Tooltip插件使其可交互的方法
2016/11/07 Javascript
JSON 数据详解及实例代码分析
2017/01/20 Javascript
flexslider.js实现移动端轮播
2017/02/05 Javascript
Webpack常见静态资源处理-模块加载器(Loaders)+ExtractTextPlugin插件
2017/06/29 Javascript
JavaScript中为事件指定处理程序的五种方式分析
2018/07/27 Javascript
AngularJS 事件发布机制
2018/08/28 Javascript
javascript触发模拟鼠标点击事件
2019/06/26 Javascript
JS document form表单元素操作完整示例
2020/01/13 Javascript
原生js实现日历效果
2020/03/02 Javascript
Python实现二分法算法实例
2015/02/02 Python
浅谈python for循环的巧妙运用(迭代、列表生成式)
2017/09/26 Python
python实现word 2007文档转换为pdf文件
2018/03/15 Python
Python生成短uuid的方法实例详解
2018/05/29 Python
numpy数组广播的机制
2019/07/12 Python
css3实现文字首尾衔接跑马灯的示例代码
2020/10/16 HTML / CSS
关于解决iframe标签嵌套问题的解决方法
2020/03/04 HTML / CSS
大门门卫岗位职责
2013/11/30 职场文书
英语专业职业生涯规划范文
2014/03/05 职场文书
建筑工地文明标语
2014/10/09 职场文书
2014年教育实习工作总结
2014/11/22 职场文书
百年孤独读书笔记
2015/06/29 职场文书
vue Element-ui表格实现树形结构表格
2021/06/07 Vue.js
讲解MySQL增删改操作
2022/05/06 MySQL