全国统一服务热线:400-633-9193

js使用formData实现批量上传

    网络     2018-11-23    1278

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

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

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

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

先看一下大概效果:

controller有两种方法:三种方式调的都是用一个接口

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

/**

 * 批量上传

 */

 @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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

<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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

//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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

<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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

//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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

<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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

//存放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数据

请求头

成功接参


  分享到:  
0.2214s