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 相关文章推荐
JQuery 绑定事件时传递参数的实现方法
Oct 13 Javascript
Riot.js 快速的JavaScript单元测试框架
Nov 09 Javascript
根据IP的地址,区分不同的地区,查看不同的网站页面的js代码
Feb 26 Javascript
JavaScript中的依赖注入详解
Mar 18 Javascript
js实现获取当前时间是本月第几周的方法
Aug 11 Javascript
Angular 4.X开发实践中的踩坑小结
Jul 04 Javascript
解决easyui日期时间框ie的兼容的问题
Mar 01 Javascript
如何检查一个对象是否为空
Apr 11 Javascript
微信小程序 bindtap 传参的实例代码
Feb 21 Javascript
JS实现横向跑马灯效果代码
Apr 20 Javascript
vue data有值,但是页面{{}} 取不到值的解决
Nov 09 Javascript
vscode自定义vue模板的实现
Jan 27 Vue.js
详解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处理斐波那契数列非递归方法
2012/02/04 PHP
php中定时计划任务的实现原理
2013/01/08 PHP
PHP使用GIFEncoder类处理gif图片实例
2014/07/01 PHP
php变量与字符串的增删改查操作示例
2020/05/07 PHP
利用ajaxfileupload插件实现文件上传无刷新的具体方法
2013/06/08 Javascript
setInterval计时器不准的问题解决方法
2014/05/08 Javascript
Node.js实现批量去除BOM文件头
2014/12/20 Javascript
js封装可使用的构造函数继承用法分析
2015/01/28 Javascript
jQuery切换所有复选框选中状态的方法
2015/07/02 Javascript
js行号显示的文本框实现效果(兼容多种浏览器 )
2015/10/23 Javascript
18个非常棒的jQuery代码片段
2015/11/02 Javascript
JavaScript判断变量是否为数组的方法(Array)
2016/02/24 Javascript
BootStrap轮播HTML代码(推荐)
2016/12/10 Javascript
深入浅析Vue中的slots/scoped slots
2018/04/03 Javascript
python获取糗百图片代码实例
2013/12/18 Python
Python实现简单的文件传输与MySQL备份的脚本分享
2016/01/03 Python
Python 爬虫图片简单实现
2017/06/01 Python
windows下python连接oracle数据库
2017/06/07 Python
Python if语句知识点用法总结
2018/06/10 Python
python集合比较(交集,并集,差集)方法详解
2018/09/13 Python
python程序控制NAO机器人行走
2019/04/29 Python
python 实现让字典的value 成为列表
2019/12/16 Python
HTML5实时语音通话聊天MP3压缩传输3KB每秒
2019/08/28 HTML / CSS
拉夫劳伦爱尔兰官方网站:Ralph Lauren爱尔兰
2020/04/10 全球购物
The North Face意大利官网:服装、背包和鞋子
2020/06/17 全球购物
描述Cookie和Session的作用,区别和各自的应用范围,Session工作原理
2015/03/25 面试题
小学教育毕业生自荐信
2013/11/18 职场文书
建筑设计学生的自我评价
2014/01/16 职场文书
护士辞职信模板
2014/01/20 职场文书
烹饪大赛策划方案
2014/05/26 职场文书
优秀大学生事迹材料
2014/12/24 职场文书
音乐教师求职信范文
2015/03/20 职场文书
2015暑期社会实践调查报告
2015/07/14 职场文书
《植物妈妈有办法》教学反思
2016/02/23 职场文书
营销策划分析:怎么策划才能更好销量产品?
2019/09/04 职场文书
Nginx缓存设置案例详解
2021/09/15 Servers