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 相关文章推荐
javascript sudoku 数独智力游戏生成代码
Mar 27 Javascript
jQuery使用动态渲染表单功能完成ajax文件下载
Jan 15 Javascript
jQuery读取和设定KindEditor值的方法
Nov 22 Javascript
javascript 回调函数详解
Nov 11 Javascript
node.js中的fs.chmodSync方法使用说明
Dec 18 Javascript
JS+CSS实现仿支付宝菜单选中效果代码
Sep 25 Javascript
javascript 中null和undefined区分和比较
Apr 19 Javascript
简单实现js拖拽效果
Jul 25 Javascript
基于jquery实现多选下拉列表
Aug 02 jQuery
浅谈react性能优化的方法
Sep 05 Javascript
vue基于element的区间选择组件
Sep 07 Javascript
Nuxt使用Vuex的方法示例
Sep 06 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
php 5.6版本中编写一个PHP扩展的简单示例
2015/01/20 PHP
php 解决扫描二维码下载跳转问题
2017/01/13 PHP
让firefox支持IE的一些方法的javascript扩展函数代码
2010/01/02 Javascript
jQuery中ajax和post处理json的不同示例对比
2014/11/02 Javascript
jQuery仿gmail实现fixed布局的方法
2015/05/27 Javascript
深入解读JavaScript中的Iterator和for-of循环
2015/07/28 Javascript
浅谈js中的in-for循环
2016/06/28 Javascript
js实现手机拍照上传功能
2017/01/17 Javascript
node.js操作MongoDB的实例详解
2017/10/11 Javascript
微信小程序canvas实现刮刮乐效果
2018/07/09 Javascript
JS html事件冒泡和事件捕获操作示例
2019/05/01 Javascript
nodejs语言实现验证码生成功能的示例代码
2019/10/13 NodeJs
element-ui中按需引入的实现
2019/12/25 Javascript
Vue 微信端扫描二维码苹果端却只能保存图片问题(解决方法)
2020/01/19 Javascript
原生JS实现多条件筛选
2020/08/19 Javascript
基于使用paramiko执行远程linux主机命令(详解)
2017/10/16 Python
python的re正则表达式实例代码
2018/01/24 Python
Python机器学习之K-Means聚类实现详解
2018/02/22 Python
Python读取Pickle文件信息并计算与当前时间间隔的方法分析
2019/01/30 Python
Python实现微信机器人的方法
2019/09/06 Python
Python实现word2Vec model过程解析
2019/12/16 Python
解决python cv2.imread 读取中文路径的图片返回为None的问题
2020/06/02 Python
奥地利领先的在线药房:SHOP APOTHEKE
2019/10/07 全球购物
linux面试题参考答案(7)
2012/10/29 面试题
Linux如何为某个操作添加别名
2015/02/05 面试题
计算机专业毕业生求职信
2014/04/30 职场文书
幼儿园优秀班主任事迹材料
2014/05/14 职场文书
项目经理任命书范本
2014/06/05 职场文书
基层党员四风问题自我剖析材料
2014/09/29 职场文书
党员组织生活会发言材料
2014/10/17 职场文书
介绍信的写法
2015/01/31 职场文书
邀请函模板
2015/02/02 职场文书
学习保证书怎么写
2015/02/26 职场文书
决心书格式范文
2015/09/23 职场文书
新西兰:最新留学学习计划书写作指南
2019/07/15 职场文书
《狼牙山五壮士》读后感:宁死不屈,视死如归
2019/08/16 职场文书