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系列(13) This? Yes,this!
Jan 18 Javascript
使用js实现一个可编辑的select下拉列表
Feb 20 Javascript
基于jquery ui的alert,confirm方案(支持换肤)
Apr 03 Javascript
javascript中innerText和innerHTML属性用法实例分析
May 13 Javascript
jQuery鼠标经过方形图片切换成圆边效果代码分享
Aug 20 Javascript
jquery动态导航插件dynamicNav用法实例分析
Sep 06 Javascript
vue2滚动条加载更多数据实现代码
Jan 10 Javascript
angularjs $http实现form表单提交示例
Jun 09 Javascript
利用Node.js了解与测量HTTP所花费的时间详解
Sep 22 Javascript
vue微信分享 vue实现当前页面分享其他页面
Dec 02 Javascript
JavaScript面试出现频繁的一些易错点整理
Mar 29 Javascript
Element Carousel 走马灯的具体实现
Jul 26 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实现文件下载简单示例(代码实现文件下载)
2014/03/10 PHP
php生成随机字符串可指定纯数字、纯字母或者混合的
2014/04/18 PHP
ThinkPHP之N方法实例详解
2014/06/20 PHP
PHP设计模式之适配器模式代码实例
2015/05/11 PHP
php验证码实现代码(3种)
2015/09/07 PHP
php基于闭包实现函数的自调用(递归)实例分析
2016/11/11 PHP
thinkPHP模板中for循环与switch语句用法示例
2016/11/30 PHP
PHP实现的简单sha1加密功能示例
2017/08/27 PHP
yii2.0整合阿里云oss上传单个文件的示例
2017/09/19 PHP
php 多进程编程父进程的阻塞与非阻塞实例分析
2020/02/22 PHP
Javascript加载速度慢的解决方案
2014/03/11 Javascript
javascript实现数组内值索引随机化及创建随机数组的方法
2015/08/10 Javascript
JavaScript的removeChild()函数用法详解
2015/12/27 Javascript
javascript学习之json入门
2016/12/22 Javascript
jQuery+C#实现参数RSA加密传输功能【附jsencrypt.js下载】
2017/06/26 jQuery
nodejs简单读写excel内容的方法示例
2018/03/16 NodeJs
node 使用 async 控制并发的方法
2018/05/07 Javascript
angular 未登录状态拦截路由跳转的方法
2018/10/09 Javascript
使用canvas实现一个vue弹幕组件功能
2018/11/30 Javascript
记录vue项目中遇到的一点小问题
2019/05/14 Javascript
JavaScript onclick事件使用方法详解
2020/05/15 Javascript
jquery插件实现轮播图效果
2020/10/19 jQuery
分享一个简单的python读写文件脚本
2017/11/25 Python
python读取并定位excel数据坐标系详解
2019/06/26 Python
django之对FileField字段的upload_to的设定方法
2019/07/28 Python
PyCharm无法引用自身项目解决方式
2020/02/12 Python
logging level级别介绍
2020/02/21 Python
Matplotlib自定义坐标轴刻度的实现示例
2020/06/18 Python
斯洛伐克时尚服装网上商店:Cellbes
2016/10/20 全球购物
汽车维修专业个人求职信范文
2014/01/01 职场文书
留学推荐信中文范文三篇
2014/01/25 职场文书
优秀员工获奖感言
2014/03/01 职场文书
项目建议书模板
2014/05/12 职场文书
初中班级口号
2014/06/09 职场文书
中职毕业生自我鉴定
2014/09/13 职场文书
2016年世界艾滋病日宣传活动总结
2016/04/01 职场文书